SurfaceFlinger.cpp revision ef7b9c7eac036cc1230c64821039d18f8cbd2c1c
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
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
391a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
44d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
481c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
56d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
571f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
60118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
64a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
67bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
68bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
7999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
8099b49840d309727678b77403d6cc9f920111623fMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
8652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
89a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
918afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
93a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
983330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
101a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
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    }
1148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
115c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
116c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
132a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
134a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
13899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
13999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
1453165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    d.orientation = DisplayState::eOrientationDefault;
1468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
14899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
150a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1537e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15596f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
15696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
15796f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
15896f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
15996f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1679a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
169b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
174a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1753330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1761f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1771f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1781f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1791f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1801f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
181921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
1821f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1831f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
185a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
186a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
187a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
191921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
192921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
193921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
194921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
195921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
196921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
197921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
198921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
199921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
201921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
202921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
203921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
204921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
205a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
206a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
207a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
208a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
211a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
212a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
226a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
229a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
231a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
235a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
261a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
283a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
284a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
2868b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
2908b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
2937303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2958b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
301a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
302a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
303a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
304a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
305a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
306a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3079575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3089575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3099575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3109575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3119575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3129575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3139575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3149575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3159575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
320ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
321ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
324a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
325a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
326a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
327a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
328a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
329a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
330a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
331a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
332a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
333a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
334a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
335a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
336a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
337a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
338a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
339a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
340a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
341a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
342a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
35034a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
35134a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
3551a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<FramebufferSurface> fbs = FramebufferSurface::create();
3561a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    if (fbs == NULL) {
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3611a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
3621a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
3651a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    ANativeWindow* const anw = stc.get();
3661a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    anw->query(anw, NATIVE_WINDOW_FORMAT, &format);
36734a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
36834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
37192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mCurrentState.displays.add(DisplayDevice::DISPLAY_ID_MAIN, DisplayDeviceState());
3721a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
37392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDisplays.add(DisplayDevice::DISPLAY_ID_MAIN, hw);
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
3764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
37734a09ba1efd706323a15633da5044b352988eb5fJesse Hall    initializeGL(mEGLDisplay, surface);
378d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
379028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
380028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventThread = new EventThread(this);
381028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    mEventQueue.setEventThread(mEventThread);
382028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
3838630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
384888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
38592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
38692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
38792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
3888630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
390d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
391d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
392a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
393a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
3948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
398a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
399a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
400a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
401a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
402a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
403a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
409a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
410a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
411a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
412a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
414d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
415582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
416582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
417134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
418582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
419134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
420134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
421134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
422134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
423134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
424134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
425134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
426582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
427582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
428582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
429582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
430582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
431134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
432134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
433134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
434134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
435582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
436582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
437134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
438134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
439134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
440134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
441134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
442134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
443134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
444134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
445582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
446582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
447582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
448582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
449582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
450134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
451134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
456c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianstatus_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
4571e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    // TODO: this is here only for compatibility -- should go away eventually.
4581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    if (uint32_t(dpy) >= 1) {
459c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian        return BAD_INDEX;
460c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
4614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
4624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->w = hw->getWidth();
4634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->h = hw->getHeight();
4644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->xdpi = hw->getDpiX();
4654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->ydpi = hw->getDpiY();
466888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    info->fps = float(1e9 / getHwComposer().getRefreshPeriod());
4674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->density = hw->getDensity();
4684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    info->orientation = hw->getOrientation();
469888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    // TODO: this needs to go away (currently needed only by webkit)
4704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
471888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
472c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
473c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
474d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
475d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
476d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
4778aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
478bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
479bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
4803094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
4813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
4823094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
4833094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
4843094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4853094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
4863094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
487d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        result = eglCreateWindowSurface(mEGLDisplay,
488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
4893094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
4903094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
4913094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
4923094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
4933094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
4953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5033094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
505d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        eglDestroySurface(mEGLDisplay, old_surface);
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
51599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
51699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
51799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
51899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
51999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
52199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
52299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
52599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
52699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
52799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
52899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
52999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5518630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
5528630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
5538630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5548630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5558630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
5568630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
5578630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5588630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
5601c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
56199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
5624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
5634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
5644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
5654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
5664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
5684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
5694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
5744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
5754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
57787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
5784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
58287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
5834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
5843a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
5864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
587a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
58852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
58987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
59087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
5913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
5923b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
5933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
5943b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
5953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
59687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
59792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
5984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
59987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region opaqueRegion;
60087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Region dirtyRegion;
60187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            computeVisibleRegions(currentLayers,
6024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                    hw->getLayerStack(), dirtyRegion, opaqueRegion);
6034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
60487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
60587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            Vector< sp<LayerBase> > layersSortedByZ;
60687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            const size_t count = currentLayers.size();
60787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
60887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                const Layer::State& s(currentLayers[i]->drawingState());
6094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                if (s.layerStack == hw->getLayerStack()) {
61087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    if (!currentLayers[i]->visibleRegion.isEmpty()) {
61187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                        layersSortedByZ.add(currentLayers[i]);
61287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
61387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
6164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.set(hw->getBounds());
6174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
6183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
62152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
62252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
62352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
62452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const bool workListsDirty = mHwWorkListDirty;
62552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mHwWorkListDirty = false;
62692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
6284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
62952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
630303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
6311e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
6321e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            if (hwc.createWorkList(id, count) >= 0) {
6331e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                HWComposer::LayerListIterator cur = hwc.begin(id);
6341e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                const HWComposer::LayerListIterator end = hwc.end(id);
6351e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
6361e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    const sp<LayerBase>& layer(currentLayers[i]);
6371e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian
6381e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    if (CC_UNLIKELY(workListsDirty)) {
6391e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        layer->setGeometry(hw, *cur);
6401e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        if (mDebugDisableHWC || mDebugRegion) {
6411e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                            cur->setSkip(true);
6421e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                        }
64352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                    }
64452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
6451e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    /*
6461e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * update the per-frame h/w composer data for each layer
6471e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     * and build the transparent region of the FB
6481e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                     */
6491e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                    layer->setPerFrameData(hw, *cur);
6501e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
65152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
65287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
65352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
65452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
65552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
65652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
65752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
65892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
6594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
660303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
66187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // transform the dirty region into this screen's coordinate space
6624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& planeTransform(hw->getTransform());
66387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region dirtyRegion;
66487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (repaintEverything) {
6654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
66652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
6674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion = planeTransform.transform(hw->dirtyRegion);
6684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.andSelf(hw->bounds());
66987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
6704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->dirtyRegion.clear();
671b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
67252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (!dirtyRegion.isEmpty()) {
6734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            if (hw->canDraw()) {
67452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                // repaint the framebuffer (if needed)
67552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                handleRepaint(hw, dirtyRegion);
67652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
67787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
67852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
6794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6813094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
68252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
68387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
68452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
68552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian#if 1
6864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
6934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
6954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
6994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
7024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
7043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
7054297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(getDisplayDevice(0));
7064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw->getVisibleLayersSortedByZ() );
7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
7084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
7094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
710fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                layer->draw(hw);
7114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
7123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
7153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7164297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->compositionComplete();
7174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
7183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
7204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
7214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
72487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian#endif
7254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
730841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
731b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
732a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
733a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
734c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
73552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
73652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
73792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
73952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
7404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
74152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            const size_t count = currentLayers.size();
7421e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const int32_t id = hw->getDisplayId();
7431e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
7441e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
74552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
74652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian                const sp<LayerBase>& layer(currentLayers[i]);
747d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                layer->setAcquireFence(hw, *cur);
748c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
749c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
7504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->flip(hw->swapRegion);
7514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->swapRegion.clear();
752c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
753c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
754ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
75552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: eventually commit() won't take arguments
7564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
75752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
75852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
75992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
7604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
7614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
76252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
76352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        if (hwc.initCheck() == NO_ERROR) {
7641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            int32_t id = hw->getDisplayId();
7651e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
7661e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
76752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
768d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
76952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
77052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        } else {
7714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
77252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
773d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
77452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
775ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
77652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
77752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
778e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
779e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
780a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
781a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
786841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
787841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
788ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
789ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
790ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
791ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
792ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
793ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
794ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
795ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
796ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
797ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
798ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
799ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
80087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
801ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
802ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
803ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
804ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
805ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
8063d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
8093d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
8103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
821076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
83692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
83792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
83892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
83992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        const KeyedVector<int32_t, DisplayDeviceState>& curr(mCurrentState.displays);
84092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        const KeyedVector<int32_t, DisplayDeviceState>& draw(mDrawingState.displays);
84192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
84392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
84492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t dc = draw.size();
84592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
84692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
84792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
84892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
84992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
85092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
85192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                if (curr.indexOfKey(draw[i].id) < 0) {
85292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
85392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
85492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        mDisplays.removeItem(draw[i].id);
85592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
85692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
85792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
85892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
85992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
86092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
86192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (state.layerStack != draw[i].layerStack) {
8624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
86328947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian                        disp->setLayerStack(state.layerStack);
86492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
86592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    if (curr[i].orientation != draw[i].orientation) {
8664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
8674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                        disp->setOrientation(state.orientation);
86892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
86992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
87092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
87192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
87292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
87392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
87492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
87592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                if (mDrawingState.displays.indexOfKey(curr[i].id) < 0) {
87692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // FIXME: we need to pass the surface here
8771a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis                    sp<DisplayDevice> disp = new DisplayDevice(this, curr[i].id, 0, 0, mEGLConfig);
87892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    mDisplays.add(curr[i].id, disp);
87992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
88092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8830aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
8840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8880aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
8890aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
8900aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
89148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
8930aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
8943d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
8953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8960aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
89787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                if (currentLayers.indexOf(layer) < 0) {
8980aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
89987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    // TODO: we could traverse the tree from front to back and
90087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    //       compute the actual visible region
9014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could cache the transformed region
9024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Layer::State front(layer->drawingState());
9034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region visibleReg = front.transform.transform(
9044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            Region(Rect(front.active.w, front.active.h)));
90587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    invalidateLayerStack(front.layerStack, visibleReg);
9060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
9070aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
9124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
9144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
9154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
9164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
9174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
9194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
9204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
9214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
9224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
9244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
9254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
9264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
93087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
93187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
933841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
934841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
93987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
943076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
946970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        // only consider the layers on the given later stack
94987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
95087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
95187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
952ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
953ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
956ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
959ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
970ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
9733165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
974a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
9754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
977ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
978ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
979ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
9804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
9814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
9824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
9844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
9854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
9864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
9874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
9884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
9894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
9904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
9914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
9924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
9934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
9944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
995ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
997ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
9984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
999ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1000ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1001ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1002ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1003ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1007ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1008ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1009ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1010ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1011ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1012ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1024a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1025ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1026ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1027ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1028ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1029ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1030ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1031ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1032ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1033ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1034ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1035a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1036ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1039ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1040ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
104587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1047ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
10498b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
105987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
106092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
10624297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
10634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
106492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
106592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
106687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
106787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
106887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10701c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
107299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10731bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
10764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
10774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
10784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
10794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
108087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
108187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Layer::State s(layer->drawingState());
108287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
10834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10844da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
10853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1088ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1089ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1090ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1091ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1092ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
109399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
109499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
109599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
109699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
109799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
109899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
109999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
110099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
110199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
110299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
110399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
110499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
110599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
110699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
110799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
110899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
11094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
111087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1112841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1113841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
111487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
111587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1116b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
11174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
112087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        debugFlashRegions(hw, dirtyRegion);
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
11240f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
112529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
112629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
112729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
11284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
11300f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
113129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1132df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
113395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
11340f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
11354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
113729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
11384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
11394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    composeSurfaces(hw, dirtyRegion);
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1145d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1146d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    const size_t count = currentLayers.size();
1147d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1148d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian        currentLayers[i]->onPostComposition();
1149d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    }
1150d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
11519c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
11524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11578630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
11581e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    int32_t id = hw->getDisplayId();
11591e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
11601e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1161a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
11621e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
116352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (cur==end || fbLayerCount) {
1164a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
11650f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        DisplayDevice::makeCurrent(hw, mEGLContext);
1166a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // set the frame buffer
116852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glMatrixMode(GL_MODELVIEW);
116952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        glLoadIdentity();
1170a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1171a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
11721e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
1173b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1174b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1175b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1176b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1177b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1178b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1179b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1180b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
11814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const Region region(hw->undefinedRegion.intersect(dirty));
1182b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
118387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1184b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
118587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                drawWormhole(region);
1186b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1187a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
11884b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1189a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1190a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1191a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
11924b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
11934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
1194a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
11954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const Transform& tr = hw->getTransform();
1196a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1197a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
11984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1199a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1200a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
12013e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1202a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1203b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1204b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
12051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1206a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
12076ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1208a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1209a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1210a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
12111b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
12124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1213a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1214a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1215a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
12164b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
12174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
122187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirtyRegion)
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t flags = hw->getFlags();
12244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const int32_t height = hw->getHeight();
12254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->swapRegion.isEmpty()) {
122653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
122753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
12280a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12290f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
12300f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
12314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                dirtyRegion.bounds() : hw->bounds());
12321b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
12330a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
12340a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1235c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1236c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
12400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
12410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
12420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
12430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
12440a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
12450926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
124787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator it = dirtyRegion.begin();
124887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region::const_iterator const end = dirtyRegion.end();
124920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
125020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
125253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
125353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
125453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
125553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12600a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->flip(hw->swapRegion);
1262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
12640a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::drawWormhole(const Region& region) const
1268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1269f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1270b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1271f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1272b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1273f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1274f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1275f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1276f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1277f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1278f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1279f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1280f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1281f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1282f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1283f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1284f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1285f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1286f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1287f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1288f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1289f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
129296f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
129396f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
12941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
129596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
12964f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
12974f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
129896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1299921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1300921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
130196f0819f81293076e652792794a961543e6750d7Mathias Agopian
13024f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
130396f0819f81293076e652792794a961543e6750d7Mathias Agopian}
130496f0819f81293076e652792794a961543e6750d7Mathias Agopian
130596f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
130696f0819f81293076e652792794a961543e6750d7Mathias Agopian{
130796f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
130896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
130996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
131096f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
131196f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1314076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1318076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
132676cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
132776cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
132976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
133076cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
133176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13328c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13332f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13340b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13353d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13363d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
133796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
133896f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1342dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1343dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1344dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1345dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1346dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1352bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
135699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13628b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
13638b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
13648b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
13658b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
13668b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1367698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1368cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
13693165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    int orientation = DisplayState::eOrientationUnchanged;
13708b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    if (displays.size()) {
13718b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        // TODO: handle all displays
13728b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        orientation = displays[0].orientation;
13738b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    }
13748b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian
137528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
137692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // FIXME: don't hardcode display id here
137792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    if (mCurrentState.displays.valueFor(0).orientation != orientation) {
13783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (uint32_t(orientation) <= DisplayState::eOrientation270) {
137992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            mCurrentState.displays.editValueFor(0).orientation = orientation;
138028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
13813165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        } else if (orientation != DisplayState::eOrientationUnchanged) {
138232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1383b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1384b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1385b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1386b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1387698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1388698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1389698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1390698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
139128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1392698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1393386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
139428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1395386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
139628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1397698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1398386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1399386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1400386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1401386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1402386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1403386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1404386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1405386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1406386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1407386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
140832397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1409386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1410386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1411386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1412cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
14170ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
14180ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
14190ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1423076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1424a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
14256e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
14266e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1427921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
14286e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
14296e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
14306e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
14318b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1432921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
14333165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
14343165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
1435921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
14373165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceBlur:
14383165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
1439921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
14413165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceScreenshot:
1442921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1443118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
144796f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1448285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
144996f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
14518b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
145296f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1453a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
14541c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
145596f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1461921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1462f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
146396f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
14641c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
146792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1473a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1474a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1475a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14768f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1477a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1481a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1482a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1483a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1484a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1485a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
148696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1487f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
148899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1489921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1495921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1496f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
149796f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
149996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1500118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1501118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1502118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1503921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1504118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1505118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1506118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1507118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1511921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
15129a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
15139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
15149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
15159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
15168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
15170aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
15180aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
15190aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
15209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
15219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
152248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
15230aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
152496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1525b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
152648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
152748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
152848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
152948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
153048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
15319a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
15329a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
15339a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1535921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1537759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1538ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1539ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1540ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1541ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1542ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1543ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1544ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1545ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1546ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1547ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1548e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1549ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1550f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1551e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1552ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1553ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1554ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
155896f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
15653165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1566698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
15693165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1570be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian            // NOTE: index needs to be calculated before we update the state
1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
15803165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
15853165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1586698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1587698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1588698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
15893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1590698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1591698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1592698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
15933165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1594698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1595698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1596698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
15973165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eVisibilityChanged) {
1598698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1599698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1600698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
16013165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1602f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1603f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1604f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
16053165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1606be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian            // NOTE: index needs to be calculated before we update the state
1607be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1608be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1609be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1610be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1611be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian                // we need traversal (state changed)
1612be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian                // AND transaction (list changed)
1613be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1614be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian            }
16158785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian        }
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1617698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1621b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
16238e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
16244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
16258630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
16264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
162722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
16318e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
16324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // XXX: this should be per DisplayDevice
16334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->isScreenAcquired()) {
163422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
16354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->releaseScreen();
16368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
16418e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1648b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1649b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1650b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1651b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1652b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16558e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1656b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1657b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1658b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1659b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1660b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1661b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1662b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1663b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1664b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1665b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1666b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1667b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1668b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1669b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1670b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16731d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
167699b49840d309727678b77403d6cc9f920111623fMathias Agopian
167799b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
16859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
16869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
16879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
16889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
16899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
16909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
16929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
16938b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
16949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
16959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
16969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
169982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
170082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
170125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
170225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
170325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
170425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
170525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
170625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
170735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
170825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
170925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
171025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
171125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
171435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
171625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
172135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
172582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
172682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
172782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
172848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
173148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
173648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
173725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
173825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
173925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
174025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
174125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
174225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
174325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
174425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
174525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
174625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
174725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
174825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
174982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
175082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
175182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
175282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
175382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
175482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
175582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
175682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
175748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
175882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
175982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
176082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
176182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
176282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
176382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
176482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
176582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
176682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
176782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
176882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
176982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
177082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1771ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
177225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
177325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
177425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
177525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
177625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
177725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
177825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
177925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
178025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
178125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
178225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
178325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
178425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
178525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
178625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
178725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
178825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
178925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
179025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
179282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
179682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1800bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
180282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
180482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
180882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
181182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1812bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1816ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
181982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
182182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
18241b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
182782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18281b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18311b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
1832888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
18334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
183682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
183782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
183982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1840d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
1842d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian            eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
184382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
184682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
18484297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
18514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1856c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1859b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1860b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1863c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
1864888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian            1e9 / hwc.getRefreshPeriod(),
18654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDpiX(),
18664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDpiY(),
18674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getDensity());
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
187382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
188182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
188282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
188382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
188482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
188582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
188682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
188782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
188882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
188982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
189082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
189182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ());
189382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
189482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
189582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
189682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
189782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
189882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
18994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->dump(result);
1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1907698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
19098e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
19108e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1915a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
191699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
191799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1918e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1919375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1920375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
19231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
19241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
19251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
19261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
19271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
19281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
19291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
193099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
193199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1932e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
19331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
19341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
19351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
19361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1942b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
194399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1944375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1945375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1946375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1947e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1948375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
195301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
195435b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
196353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1964cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1965cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1966cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1967cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1968cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19704d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
19714d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
19724d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
19734d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
197453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
197553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
197653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
197753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
197853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
197953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1980a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1981a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1982a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1983a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1984a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1985a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
198701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1990b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
199112839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
19954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
19964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
1997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
200453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
200587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
200699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
200753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
200853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
200959119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
201059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2013118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2014118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2015118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2016118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2017118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
20199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
202059119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
202122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
202222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
202559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
20274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
20284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
20294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
203759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
203859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
203959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2040a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2041a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2045015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
204659119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
204759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
20489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
205159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
205359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
205459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
20559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
205759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2059c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2060c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
20619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
20629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2063a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2064a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
20654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
20679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
2069fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian        layer->draw(hw);
20709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
207159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2073118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
207759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
20819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
208359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
20859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
208674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
208774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
208874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2089bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2090bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
209174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2092fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2093fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
209474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
209574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
209674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
20973b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
2098ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("invalid display %d", dpy);
209974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
21003b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
210174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
21023b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
210374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
21043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
210574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
210674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
21074297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDisplayDevice(dpy));
21084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
21094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
211074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
21113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
21124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (hw->getSecureLayerVisible()) {
2113ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGW("FB is protected: PERMISSION_DENIED");
21143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
21153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
21163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
21173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
2118ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h);
211974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
21203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
212174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
212274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
212374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
212474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
2125fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian    const bool filtering = sw != hw_w || sh != hw_h;
212674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2127ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
2128ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//            sw, sh, minLayerZ, maxLayerZ);
2129c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
213074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
213174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
213274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
213374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
213474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
213574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
213674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
213774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2138fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
213974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
214074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
214174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
214274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
214374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
214474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2145c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
214674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
214774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
214874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
214974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
215074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
215174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
215274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2153ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
215474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
215574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
215674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
215774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
215874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2159f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
21609575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
21619575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
216274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
216374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2164b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
21653165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian            if (!(flags & layer_state_t::eLayerHidden)) {
2166b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2167b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
2168fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(true);
2169fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    layer->draw(hw);
2170fcb239d3dac8bc80f28177f1951611c1d43286ffMathias Agopian                    if (filtering) layer->setFiltering(false);
2171b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2172bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
217374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
217474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
217574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
217674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
217774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
217874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
217974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
218074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
218174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
218274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
218374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
218474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
218574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
218674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2187fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
218874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
218974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
219074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
219174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
219274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
219374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
219474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
219574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
219674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
219774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
219874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
219974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
220074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
220174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
220274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
220374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
220474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
220574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
220674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
220774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
220874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
220974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
221074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
221174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2212e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
22134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->compositionComplete();
2214e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2215ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian//    ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2216c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
221774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
221874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
221974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
222074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
22211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
22221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
222374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2224bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2225bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
22261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
22271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
222899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
22291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
22301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
22331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
22351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
22361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
22371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
22381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
22391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
22401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
224174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
224274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2243bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2244bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
22451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
22461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
22471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
224874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2249bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2250bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
22511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2252bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2253bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2254bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
22551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
22561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
22581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
22591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
22611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
226274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2263bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
22641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
22651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
22661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
22671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2269bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
22701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
22711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
22721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
22731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
22741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
22751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
22761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
22771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
22781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2279921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2280921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2281921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2282921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2283921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2284921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2285921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2286921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2287921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2289be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
2290921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2291921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2292be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2293be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t ls = l->currentState().layerStack;
2294be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    uint32_t rs = r->currentState().layerStack;
2295be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
2296be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
2297be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2298921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2299921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2300be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
2301be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
2302be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
2303be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
2304921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2305921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2306921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
230892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
230992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    : id(DisplayDevice::DISPLAY_ID_MAIN), layerStack(0), orientation(0) {
2310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
23117303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
231396f0819f81293076e652792794a961543e6750d7Mathias Agopian
23149a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
23159a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
23169a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
23179a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
23189a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2319d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
23209a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
23219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2322d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2323a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2324d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2325d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2326d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2327e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2328a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2329a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
23309a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
23319a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
23329a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
23339a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
23349a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
23359a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
23369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2338