SurfaceFlinger.cpp revision 8630320433bd15aca239522e54e711ef6372ab07
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
35d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
36921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/SurfaceTextureClient.h>
38921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
41d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/gui/SharedBufferStack.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
5190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
521b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware.h"
53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
54d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
551f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
58118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian#include "LayerScreenshot.h"
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
62a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
65bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
66bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
7399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
7499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
7599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
7699b49840d309727678b77403d6cc9f920111623fMathias Agopian
7799b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
7899b49840d309727678b77403d6cc9f920111623fMathias Agopian
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    :   BnSurfaceComposer(), Thread(false),
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
8228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        mTransationPending(false),
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
86a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
87abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode(0),
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
9073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
91a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
963330b203039dea366d4981db1408a460134b2d2cMathias Agopian        mBootFinished(false),
973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface(EGL_NO_SURFACE)
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
99a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1038afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1073854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#ifdef DDMS_DEBUGGING
1088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1108afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
1118afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        DdmConnection::start(getServiceName());
1128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
1135df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#else
1145df996211d4e263feb862121cfafa7f9c8eeda68Mathias Agopian#warning "DDMS_DEBUGGING disabled"
1153854ed549012f2abf8fea7b0e6db30b104ea5547Colin Cross#endif
1168afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
117a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugRegion,       "showupdates enabled");
118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI_IF(mDebugDDMS,         "DDMS debugging enabled");
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
12299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
12399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
12499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
12699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
12799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // Wait for the main thread to be done with its initialization
12899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mReadyToRunBarrier.wait();
12999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
13099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
13199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDeleteTextures(1, &mWormholeTexName);
135a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
136a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
137a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
14199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
14299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
14399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // reset screen orientation
14599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    Vector<ComposerState> state;
1468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    Vector<DisplayState> displays;
1478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    DisplayState d;
1488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    d.orientation = eOrientationDefault;
1498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    displays.add(d);
1508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    setTransactionState(state, displays, 0);
15199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
153a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
15499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
15599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1567303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopiansp<IMemoryHeap> SurfaceFlinger::getCblk() const
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1587303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian    return mServerHeap;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1617e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
16496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
16596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
16696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
16796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1729a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
1739a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
1759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
1769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
177b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
182a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
1833330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
1841f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1851f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
1861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
1871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
1881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
189921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
1901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
193a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
194a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
195a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) {
199921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        GLuint texture;
201921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
202921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageDestroyGLTexture(GLuint texture)
203921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            : texture(texture) {
204921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
205921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
206921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            glDeleteTextures(1, &texture);
207921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
208921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
209921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
210921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(texture));
211921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
212921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
213a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::selectConfigForPixelFormat(
214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLDisplay dpy,
215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint const* attrs,
216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        PixelFormat format,
217a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig* outConfig)
218a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
219a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config = NULL;
220a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint numConfigs = -1, n=0;
221a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
222a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
223a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
224a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    for (int i=0 ; i<n ; i++) {
225a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLint nativeVisualId = 0;
226a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
227a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
228a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            *outConfig = configs[i];
229a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            delete [] configs;
230a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return NO_ERROR;
231a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    delete [] configs;
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return NAME_NOT_FOUND;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // it is to be used with WIFI displays
240a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLConfig config;
241a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint dummy;
242a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    status_t err;
243a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint attribs[] = {
244a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_SURFACE_TYPE,           EGL_WINDOW_BIT,
245a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_RECORDABLE_ANDROID,     EGL_TRUE,
246a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE
247a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
248a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
249a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (err) {
250a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        // maybe we failed because of EGL_RECORDABLE_ANDROID
251a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID");
252a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        attribs[2] = EGL_NONE;
253a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config);
254a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
255a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
256a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
257a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!");
258a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
259a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return config;
260a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262a49126087b4494f4ef50873f3a3f6727265f6621Mathias AgopianEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) {
263a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Also create our EGLContext
264a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint contextAttributes[] = {
265a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef EGL_IMG_context_priority
266a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
267a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#warning "using EGL_IMG_context_priority"
268a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
269a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
270a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#endif
271a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            EGL_NONE, EGL_NONE
272a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    };
273a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
274a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
275a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return ctxt;
276a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
278a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianvoid SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
279a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
280a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!result) {
281a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
282a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
285a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
286a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    extensions.initWithGLStrings(
287a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VENDOR),
288a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_RENDERER),
289a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_VERSION),
290a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            glGetString(GL_EXTENSIONS),
291a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VENDOR),
292a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_VERSION),
293a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
2948b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
295a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
296a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
297a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
2988b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
299a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
300a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
3017303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3038b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber    glPixelStorei(GL_PACK_ALIGNMENT, 4);
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glEnableClientState(GL_VERTEX_ARRAY);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glShadeModel(GL_FLAT);
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_DITHER);
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_CULL_FACE);
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
309a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    struct pack565 {
310a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
311a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            return (r<<11)|(g<<5)|b;
312a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        }
313a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    } pack565;
314a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const uint16_t g1 = pack565(0x17,0x2f,0x17);
3179575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glGenTextures(1, &mWormholeTexName);
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
3259575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
3269575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis
3279575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
3289575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glGenTextures(1, &mProtectedTexName);
3299575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
3309575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3319575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3329575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3339575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3349575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
3359575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glViewport(0, 0, w, h);
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glMatrixMode(GL_PROJECTION);
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glLoadIdentity();
340ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    // put the origin in the left-bottom corner
341ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // print some debugging info
344a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint r,g,b,a;
345a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
346a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g);
347a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE,  &b);
348a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a);
349a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGL informations:");
350a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getEglVendor());
351a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getEglVersion());
352a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getEglExtension());
353a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
354a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);
355a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("OpenGL ES informations:");
356a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("vendor    : %s", extensions.getVendor());
357a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("renderer  : %s", extensions.getRenderer());
358a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("version   : %s", extensions.getVersion());
359a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("extensions: %s", extensions.getExtension());
360a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
361a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopiansurface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const {
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mServerCblk;
366a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
367a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
368a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianstatus_t SurfaceFlinger::readyToRun()
369a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian{
370a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
371a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
372a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
373a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create the shared control-block
374a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mServerHeap = new MemoryHeapBase(4096,
375a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
376a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
377a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
378a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
379a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    new(mServerCblk) surface_flinger_cblk_t;
380a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
381a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
382a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize EGL
383a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
384a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglInitialize(display, NULL, NULL);
385a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
386a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // Initialize the main display
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // create native window to main display
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    sp<FramebufferSurface> anw = FramebufferSurface::create();
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ANativeWindow* const window = anw.get();
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (!window) {
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        ALOGE("Display subsystem failed to initialize. check logs. exiting...");
392a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        exit(0);
393a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
394a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
395a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize the config and context
396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    int format;
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
398a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLConfig  = selectEGLConfig(display, format);
399a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mEGLContext = createGLContext(display, mEGLConfig);
400a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
401a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // initialize our main display hardware
402a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig);
403a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mDisplayHardwares[0] = hw;
404a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
405a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    //  initialize OpenGL ES
406a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLSurface surface = hw->getEGLSurface();
407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    initializeGL(display, surface);
408d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
4098630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    // initialize the H/W composer
4108630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mHwc = new HWComposer(this,
4118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian            *static_cast<HWComposer::EventHandler *>(this),
4128630320433bd15aca239522e54e711ef6372ab07Mathias Agopian            hw->getRefreshPeriod());
4138630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
4148630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        mHwc->setFrameBuffer(display, surface);
4158630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    }
4168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
417d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    // start the EventThread
418d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mEventThread = new EventThread(this);
4198aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    mEventQueue.setEventThread(mEventThread);
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
421a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    // We're now ready to accept clients...
422d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    mReadyToRunBarrier.open();
423d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
424a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
425a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
4268b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
430a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
431a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
432a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
433a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
434a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
435a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
436a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxTextureSize() const {
437a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxTextureSize;
438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
439a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
440a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopianuint32_t SurfaceFlinger::getMaxViewportDims() const {
441a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
442a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
444a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
446d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
447582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
448582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) const {
449134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
450582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
451134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
452134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the visible layer list for the ISurface
453134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
454134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t count = currentLayers.size();
455134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
456134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(currentLayers[i]);
457134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
458582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
459582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
460582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
461582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
462582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
463134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
464134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
465134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
466134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // Check the layers in the purgatory.  This check is here so that if a
467582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // SurfaceTexture gets destroyed before all the clients are done using it,
468582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    // the error will not be reported as "surface XYZ is not authenticated", but
469134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // will instead fail later on when the client tries to use the surface,
470134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // which should be reported as "surface XYZ returned an -ENODEV".  The
471134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // purgatorized layers are no less authentic than the visible ones, so this
472134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    // should not cause any harm.
473134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    size_t purgatorySize =  mLayerPurgatory.size();
474134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    for (size_t i=0 ; i<purgatorySize ; i++) {
475134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
476134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
477582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        if (lbc != NULL) {
478582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
479582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            if (lbcBinder == surfaceTextureBinder) {
480582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis                return true;
481582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis            }
482134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
483134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
484134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
485134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    return false;
486134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
487134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
488d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
489d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
490d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
4918aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
492bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
493bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
4943094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopianvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
4951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
4963094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface result = EGL_NO_SURFACE;
4973094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    EGLSurface old_surface = EGL_NO_SURFACE;
4983094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    sp<SurfaceTextureClient> stc;
4993094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5003094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (display != NULL) {
5013094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        stc = new SurfaceTextureClient(display);
5023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        result = eglCreateWindowSurface(hw.getEGLDisplay(),
503a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian                mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
5043094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGE_IF(result == EGL_NO_SURFACE,
5053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
5063094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian                display.get());
5073094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5093094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    { // scope for the lock
5103094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        Mutex::Autolock _l(mStateLock);
5113094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        old_surface = mExternalDisplaySurface;
5123094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplayNativeWindow = stc;
5133094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        mExternalDisplaySurface = result;
5143094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        ALOGD("mExternalDisplaySurface = %p", result);
5153094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5163094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5173094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    if (old_surface != EGL_NO_SURFACE) {
5183094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // Note: EGL allows to destroy an object while its current
5193094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        // it will fail to become current next time though.
5203094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian        eglDestroySurface(hw.getEGLDisplay(), old_surface);
5213094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    }
5223094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5233094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
5243094df359d1e6e2ae8ca4e935cc093f563804c96Mathias AgopianEGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
5253094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    Mutex::Autolock _l(mStateLock);
5263094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    return mExternalDisplaySurface;
5273094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian}
5283094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
53099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
53299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
53399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
53699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
53799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
53899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
53999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
54099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
54199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
54299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
54399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
54499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
54599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
54699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
54799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
54899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
54999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
55099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
55199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
55299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
55399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
55499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
55599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
55699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
55799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
55899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
55999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianbool SurfaceFlinger::threadLoop() {
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    waitForEvent();
56399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return true;
56499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5668630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::onVSyncReceived(int dpy, nsecs_t timestamp) {
5678630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
5688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    hw.onVSyncReceived(timestamp);
5698630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    mEventThread->onVSyncReceived(dpy, timestamp);
5708630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5718630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5728630320433bd15aca239522e54e711ef6372ab07Mathias Agopianvoid SurfaceFlinger::eventControl(int event, int enabled) {
5738630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().eventControl(event, enabled);
5748630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
5758630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
5764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
5771c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
5794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
5804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
5814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
5824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
5834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
5854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
5864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
5874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
5914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
5924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    uint32_t transactionFlags = peekTransactionFlags(mask);
5934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
5944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        Region dirtyRegion;
5954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion = handleTransaction(transactionFlags);
5964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // XXX: dirtyRegion should be per screen
5974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mDirtyRegion |= dirtyRegion;
5984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
5994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
6024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
6034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handlePageFlip();
6044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
6054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion |= dirtyRegion;
6064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
6073a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
6084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
6094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    handleRefresh();
610a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
6113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (mVisibleRegionsDirty) {
6123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region opaqueRegion;
6133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Region dirtyRegion;
6143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
6153b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
6163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mDirtyRegion.orSelf(dirtyRegion);
6173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        /*
6193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         *  rebuild the visible layer list per screen
6203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian         */
6213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // TODO: iterate through all displays
6233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
6243b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        Vector< sp<LayerBase> > layersSortedByZ;
6263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const size_t count = currentLayers.size();
6273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
6283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            if (!currentLayers[i]->visibleRegion.isEmpty()) {
6293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                // TODO: also check that this layer is associated to this display
6303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layersSortedByZ.add(currentLayers[i]);
6313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
6323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
6333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        hw.setVisibleLayersSortedByZ(layersSortedByZ);
6343b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        // FIXME: mWormholeRegion needs to be calculated per screen
6373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
6383b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mWormholeRegion = Region(hw.getBounds()).subtract(
6393b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                hw.getTransform().transform(opaqueRegion) );
6403b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        mVisibleRegionsDirty = false;
6413b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        invalidateHwcGeometry();
6423b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
6433b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen, we should check all of them
6464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (mDirtyRegion.isEmpty()) {
6474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        return;
6484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
649303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
6504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // TODO: iterate through all displays
6514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const DisplayHardware& hw(getDisplayHardware(0));
65269a655caef30663403802281210363f643ceb946Mathias Agopian
6534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // XXX: dirtyRegion should be per screen
6544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // transform the dirty region into this screen's coordinate space
6554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const Transform& planeTransform(hw.getTransform());
6564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion = planeTransform.transform(mDirtyRegion);
6574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
6584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDirtyRegion.andSelf(hw.bounds());
659303d538bb012e82c6b9a98c4930a03455000f761Mathias Agopian
660b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
6614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_UNLIKELY(mHwWorkListDirty)) {
6624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // build the h/w work list
6634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleWorkList(hw);
6644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6653094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (CC_LIKELY(hw.canDraw())) {
6674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // repaint the framebuffer (if needed)
6684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleRepaint(hw);
6694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // inform the h/w that we're done compositing
6704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        postFramebuffer();
6724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    } else {
6734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // pretend we did the post
6744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        hw.compositionComplete();
6754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
6763094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
6774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    // render to the external display if we have one
6784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    EGLSurface externalDisplaySurface = getExternalDisplaySurface();
6794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (externalDisplaySurface != EGL_NO_SURFACE) {
6804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
6814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
6824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                externalDisplaySurface, externalDisplaySurface,
6834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                eglGetCurrentContext());
6844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> external failed");
6864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
6874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        if (success) {
6884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            // redraw the screen entirely...
6894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_EXTERNAL_OES);
6904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glDisable(GL_TEXTURE_2D);
6914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClearColor(0,0,0,1);
6924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
6934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glMatrixMode(GL_MODELVIEW);
6944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            glLoadIdentity();
6953b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
6963b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
6974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const size_t count = layers.size();
6984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            for (size_t i=0 ; i<count ; ++i) {
6994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const sp<LayerBase>& layer(layers[i]);
7004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                layer->drawForSreenShot(hw);
7014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            }
7023094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
7044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            ALOGE_IF(!success, "external display eglSwapBuffers failed");
7053094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            hw.compositionComplete();
7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
7083094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian
7094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        success = eglMakeCurrent(eglGetCurrentDisplay(),
7104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                cur, cur, eglGetCurrentContext());
7114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
719841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
720b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // mSwapRegion can be empty here is some cases, for instance if a hidden
721b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // or fully transparent window is updating.
722b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // in that case, we need to flip anyways to not risk a deadlock with
723b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian    // h/w composer.
724b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
7251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
7268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
7273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
7283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    size_t numLayers = layers.size();
729a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
730a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
731c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
732c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    if (hwc.initCheck() == NO_ERROR) {
733c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
734c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        const HWComposer::LayerListIterator end = hwc.end();
735c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
736c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            if (cur->getCompositionType() == HWC_OVERLAY) {
7373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian                layers[i]->setAcquireFence(*cur);
738c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            } else {
739c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall                cur->setAcquireFenceFd(-1);
740c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall            }
741c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall        }
742c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall    }
743c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
744a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    hw.flip(mSwapRegion);
7458630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    hwc.commit();
746e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
747ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
748ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        HWComposer::LayerListIterator cur = hwc.begin();
749ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        const HWComposer::LayerListIterator end = hwc.end();
750ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
7513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(&*cur);
752ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
753ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    } else {
754ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        for (size_t i = 0; i < numLayers; i++) {
7553b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            layers[i]->onLayerDisplayed(NULL);
756ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
757e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
758e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
759a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
760a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
761a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mSwapRegion.clear();
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
766841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
767841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
772ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
773ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
774ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
775ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
776ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
777ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
778ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
779ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
780ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
781ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    transactionFlags = getTransactionFlags(mask);
7824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    dirtyRegion = handleTransactionLocked(transactionFlags);
783ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
784ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
785ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
786ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
787ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
7884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
7894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
7903d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
7933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
7944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
7953d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (layersNeedTransaction) {
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
806076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const sp<LayerBase>& layer = currentLayers[i];
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Perform our own transaction if needed
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (transactionFlags & eTransactionNeeded) {
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mCurrentState.orientation != mDrawingState.orientation) {
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // the orientation has changed, recompute all visible regions
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // and invalidate everything.
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            const int dpy = 0; // TODO: should be a parameter
8261b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
82798a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian            hw.setOrientation(mCurrentState.orientation);
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8291b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            // FIXME: mVisibleRegionsDirty & mDirtyRegion should this be per DisplayHardware?
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8340aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
8350aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            // layers have been added
836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8390aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // some layers might have been removed, so
8400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        // we need to update the regions they're exposing.
8410aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian        if (mLayersRemoved) {
84248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            mLayersRemoved = false;
843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
8440aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
8453d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            const size_t count = previousLayers.size();
8463d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian            for (size_t i=0 ; i<count ; i++) {
8470aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                const sp<LayerBase>& layer(previousLayers[i]);
8480aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                if (currentLayers.indexOf( layer ) < 0) {
8490aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                    // this layer is not visible anymore
8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could traverse the tree from front to back and compute the actual visible region
8514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    // TODO: we could cache the transformed region
8524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Layer::State front(layer->drawingState());
8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region visibleReg = front.transform.transform(
8544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            Region(Rect(front.active.w, front.active.h)));
8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    dirtyRegion.orSelf(visibleReg);
8560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian                }
8570aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
8624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
8634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
8674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
8684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
8694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
8704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
8714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
8724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
8734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
8754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
8764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransationPending = false;
8774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
8811bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
883841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
884841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    dirtyRegion.clear();
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
893076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const sp<LayerBase>& layer = currentLayers[i];
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
896970112231e887c8a14441ec4fed55342e019fc8cMathias Agopian        const Layer::State& s(layer->drawingState());
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
900ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
904ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
908ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
910ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
911ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
916ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
917ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
91999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
920a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            const bool translucent = !layer->isOpaque();
9214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            Rect bounds(layer->computeBounds());
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
923ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
924ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
925ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
9264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    Region transparentRegionScreen;
9274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
9284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
9294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
9304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
9314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen = tr.transform(s.transparentRegion);
9324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
9334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
9344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
9354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            transparentRegionScreen.clear();
9364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
9374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
9384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        transparentRegionScreen = s.transparentRegion;
9394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
9404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    visibleRegion.subtractSelf(transparentRegionScreen);
941ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
943ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
9444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
948ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
949ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
953ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
955ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
956ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
9674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
970a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
973ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
974ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
975ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
976ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
977ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
978ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
979ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
980ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
981a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
9834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
9844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
985ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
986ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirtyRegion.orSelf(dirty);
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
993ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
9958b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Store the visible region is screen space
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    opaqueRegion = aboveOpaqueLayers;
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias AgopianRegion SurfaceFlinger::handlePageFlip()
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
10061c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
10074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
100899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10091bbafb96101de04c43adb5e3ca2494070d20a46aMathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
10124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    const size_t count = currentLayers.size();
10134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    sp<LayerBase> const* layers = currentLayers.array();
10144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
10154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const sp<LayerBase>& layer(layers[i]);
10164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
10174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10184da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
10193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
10200dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    return dirtyRegion;
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1024ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1025ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1026ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1027ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1028ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::handleRefresh()
103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    bool needInvalidate = false;
103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
103399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    const size_t count = currentLayers.size();
103499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
103599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        if (layer->onPreComposition()) {
103799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian            needInvalidate = true;
103899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        }
103999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
104099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (needInvalidate) {
104199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalLayerUpdate();
104299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
104399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
10461b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
1047a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian{
1048a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    mHwWorkListDirty = false;
10498630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
1050a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (hwc.initCheck() == NO_ERROR) {
10513b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
1052a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        const size_t count = currentLayers.size();
1053a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        hwc.createWorkList(count);
10543e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian
10553e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        HWComposer::LayerListIterator cur = hwc.begin();
10563e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        const HWComposer::LayerListIterator end = hwc.end();
10573e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
10584fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            currentLayers[i]->setGeometry(hw, *cur);
105953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            if (mDebugDisableHWC || mDebugRegion) {
10603e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                cur->setSkip(true);
106173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian            }
1062a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        }
1063a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
1064a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
1065b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian
10661b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::handleRepaint(const DisplayHardware& hw)
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1068841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1069841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1070b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
10710656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(mDebugRegion)) {
10741b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        debugFlashRegions(hw);
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // set the frame buffer
1078b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glMatrixMode(GL_MODELVIEW);
1079b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    glLoadIdentity();
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = hw.getFlags();
1082a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (flags & DisplayHardware::SWAP_RECTANGLE) {
108329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
108429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
108529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
1086a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        mDirtyRegion.set(mSwapRegion.bounds());
1087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
108895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        if (flags & DisplayHardware::PARTIAL_UPDATES) {
108929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1090df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
109195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
109229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // rectangle instead of a region (see DisplayHardware::flip())
10930656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mDirtyRegion.set(mSwapRegion.bounds());
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
109529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mDirtyRegion.set(hw.bounds());
10970656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian            mSwapRegion = mDirtyRegion;
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    setupHardwareComposer(hw);
11021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    composeSurfaces(hw, mDirtyRegion);
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11049c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
11059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    mSwapRegion.orSelf(mDirtyRegion);
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDirtyRegion.clear();
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11091b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
11118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
11123e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
11133e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
11143e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur == end) {
11159c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian        return;
1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1117a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
11183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
111945721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    size_t count = layers.size();
1120a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1121e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(hwc.getNumLayers() != count,
112245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
112345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian            hwc.getNumLayers(), count);
1124a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
112545721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    // just to be extra-safe, use the smallest count
112624925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    if (hwc.initCheck() == NO_ERROR) {
112724925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
112824925bfba22ac24de8dedc8f2c1cad5be7ade14fErik Gilling    }
1129a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
113045721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian    /*
113145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  update the per-frame h/w composer data for each layer
113245721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     *  and build the transparent region of the FB
113345721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian     */
11343e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1135f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
11363e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian        layer->setPerFrameData(*cur);
1137f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    }
1138f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian    status_t err = hwc.prepare();
1139e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
1140f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian}
1141f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian
11421b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
1143f384cc3008a25ad1b00403aca0cc001547f029c6Mathias Agopian{
11448630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
11453e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    HWComposer::LayerListIterator cur = hwc.begin();
11463e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    const HWComposer::LayerListIterator end = hwc.end();
1147cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian
1148cd20eb09c4752531c1ab1a0084474ef530a5d44fMathias Agopian    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
11493e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian    if (cur==end || fbLayerCount) {
1150a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
115145721773e1a68e96da4b6cc04cef276bae7ca3e9Mathias Agopian
1152b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        if (hwc.getLayerCount(HWC_OVERLAY)) {
1153b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1154b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1155b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
1156b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // GPUs doing a "clean slate" glClear might be more efficient.
1157b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
1158b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClearColor(0, 0, 0, 0);
1159b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            glClear(GL_COLOR_BUFFER_BIT);
1160b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1161b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
1162b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            if (!mWormholeRegion.isEmpty()) {
1163b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
1164b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                drawWormhole();
1165b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1166a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
11674b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
1168a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        /*
1169a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         * and then, render the layers targeted at the framebuffer
1170a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian         */
11714b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
11723b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
1173a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        const size_t count = layers.size();
11744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        const Transform& tr = hw.getTransform();
1175a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall        for (size_t i=0 ; i<count ; ++i) {
1176a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            const sp<LayerBase>& layer(layers[i]);
11774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
1178a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian            if (!clip.isEmpty()) {
1179a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
11803e8b853d67c737abdb363f9c978e7d83eac4d888Mathias Agopian                    if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
1181a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                            && layer->isOpaque()) {
1182b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // never clear the very first layer since we're
1183b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                        // guaranteed the FB is already cleared
11841b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                        layer->clearWithOpenGL(hw, clip);
1185a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
11866ee93c0d36dff1339eb2428be2d65441398e6e5fJesse Hall                    ++cur;
1187a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    continue;
1188a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                }
1189a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                // render the layer
11901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                layer->draw(hw, clip);
11914b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian            }
1192a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            if (cur != end) {
1193a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall                ++cur;
1194a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
11954b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
11964b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopianvoid SurfaceFlinger::debugFlashRegions(const DisplayHardware& hw)
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
12010a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    const uint32_t flags = hw.getFlags();
120253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    const int32_t height = hw.getHeight();
12030656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    if (mSwapRegion.isEmpty()) {
120453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian        return;
120553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian    }
12060a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1207a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
12080a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
12090a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian                mDirtyRegion.bounds() : hw.bounds());
12101b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        composeSurfaces(hw, repaint);
12110a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian    }
12120a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
1213c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1214c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    glDisable(GL_BLEND);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    static int toggle = 0;
12180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    toggle = 1 - toggle;
12190926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (toggle) {
12200a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 0, 1, 1);
12210926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    } else {
12220a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        glColor4f(1, 1, 0, 1);
12230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
122520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator it = mDirtyRegion.begin();
122620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    Region::const_iterator const end = mDirtyRegion.end();
122720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian    while (it != end) {
122820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian        const Rect& r = *it++;
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GLfloat vertices[][2] = {
123053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.top },
123153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.left,  height - r.bottom },
123253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.bottom },
123353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                { r.right, height - r.top }
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        };
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glVertexPointer(2, GL_FLOAT, 0, vertices);
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
12380a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian
12390656a68380d01de4136933901b2c322cf9ab0d7eMathias Agopian    hw.flip(mSwapRegion);
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (mDebugRegion > 1)
12420a91775c4df380d6a5b7f3ccad5127388ac01306Mathias Agopian        usleep(mDebugRegion * 1000);
1243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::drawWormhole() const
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const Region region(mWormholeRegion.intersect(mDirtyRegion));
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (region.isEmpty())
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1251f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
1252b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glDisable(GL_TEXTURE_2D);
1253f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glDisable(GL_BLEND);
1254b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian    glColor4f(0,0,0,0);
1255f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian
1256f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    GLfloat vertices[4][2];
1257f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vertices);
1258f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator it = region.begin();
1259f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    Region::const_iterator const end = region.end();
1260f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    while (it != end) {
1261f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        const Rect& r = *it++;
1262f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][0] = r.left;
1263f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[0][1] = r.top;
1264f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][0] = r.right;
1265f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[1][1] = r.top;
1266f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][0] = r.right;
1267f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[2][1] = r.bottom;
1268f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][0] = r.left;
1269f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        vertices[3][1] = r.bottom;
1270f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1271f74e8e0602100e048c13ea262f0c19c3b8738b6fMathias Agopian    }
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
127496f0819f81293076e652792794a961543e6750d7Mathias Agopianssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
127596f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<LayerBaseClient>& lbc)
12761b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
127796f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
12784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    size_t name = client->attachLayer(lbc);
12794f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
128096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1281921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1282921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
128396f0819f81293076e652792794a961543e6750d7Mathias Agopian
12844f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    return ssize_t(name);
128596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
128696f0819f81293076e652792794a961543e6750d7Mathias Agopian
128796f0819f81293076e652792794a961543e6750d7Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
128896f0819f81293076e652792794a961543e6750d7Mathias Agopian{
128996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
129096f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = purgatorizeLayer_l(layer);
129196f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR)
129296f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
129396f0819f81293076e652792794a961543e6750d7Mathias Agopian    return err;
1294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1296076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
1300076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
1301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
13033d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopianstatus_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
13079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
130876cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // First add the layer to the purgatory list, which makes sure it won't
130976cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    // go away, then remove it from the main list (through a transaction).
13109a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    ssize_t err = removeLayer_l(layerBase);
131176cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    if (err >= 0) {
131276cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian        mLayerPurgatory.add(layerBase);
131376cd4ddc6ad664257739b3d3713fd9ebdc9a4ad9Mathias Agopian    }
13148c0a3d75c8823e179d19c6303f64e669975a4d85Mathias Agopian
13152f4b68d21c1a58cbcb1e6929fb241e425a8f7b5dJesse Hall    mLayersPendingRemoval.push(layerBase);
13160b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian
13173d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // it's possible that we don't find a layer, because it might
13183d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    // have been destroyed already -- this is not technically an error
131996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // from the user because there is a race between Client::destroySurface(),
132096f0819f81293076e652792794a961543e6750d7Mathias Agopian    // ~Client() and ~ISurface().
13219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
13229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
13239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1324dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
1325dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian{
1326dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1327dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1328dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1334bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
1335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
133899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
13458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
13468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
13478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
13488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
1349698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
1350cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
13518b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    int orientation = eOrientationUnchanged;
13528b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    if (displays.size()) {
13538b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        // TODO: handle all displays
13548b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        orientation = displays[0].orientation;
13558b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    }
13568b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian
135728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1358b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    if (mCurrentState.orientation != orientation) {
1359b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1360b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            mCurrentState.orientation = orientation;
136128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis            transactionFlags |= eTransactionNeeded;
1362b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        } else if (orientation != eOrientationUnchanged) {
136332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
1364b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis                    orientation);
1365b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis        }
1366b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1367b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    const size_t count = state.size();
1369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1370698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1371698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        sp<Client> client( static_cast<Client *>(s.client.get()) );
137228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        transactionFlags |= setClientStateLocked(client, s.state);
1373698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1374386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
137528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1376386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
137728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1378698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1380386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1381386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
1382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            mTransationPending = true;
1383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
1384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        while (mTransationPending) {
1385386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1386386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1387386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
138932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1390386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                mTransationPending = false;
1391386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1392386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1393cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1397921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<ISurface> SurfaceFlinger::createLayer(
13980ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
13990ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
14000ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t flags)
1403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1404076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    sp<LayerBaseClient> layer;
1405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    sp<ISurface> surfaceHandle;
14066e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian
14076e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1408921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
14096e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
14106e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian        return surfaceHandle;
14116e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
14128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1413921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (flags & eFXSurfaceMask) {
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceNormal:
1416921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createNormalLayer(client, d, w, h, flags, format);
1417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceBlur:
14191293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // for now we treat Blur as Dim, until we can implement it
14201293a8eb567fd63c072a6970fa9dcf37d076059fMathias Agopian            // efficiently.
1421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case eFXSurfaceDim:
1422921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createDimLayer(client, d, w, h, flags);
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1424118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        case eFXSurfaceScreenshot:
1425921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            layer = createScreenshotLayer(client, d, w, h, flags);
1426118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian            break;
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (layer != 0) {
143096f0819f81293076e652792794a961543e6750d7Mathias Agopian        layer->initStates(w, h, flags);
1431285dbde2e0cd0057be070ded3be8f5f453147edcMathias Agopian        layer->setName(name);
143296f0819f81293076e652792794a961543e6750d7Mathias Agopian        ssize_t token = addClientLayer(client, layer);
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        surfaceHandle = layer->getSurface();
14348b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber        if (surfaceHandle != 0) {
143596f0819f81293076e652792794a961543e6750d7Mathias Agopian            params->token = token;
1436a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian            params->identity = layer->getIdentity();
14371c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        }
143896f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return surfaceHandle;
1442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1444921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<Layer> SurfaceFlinger::createNormalLayer(
1445f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
144696f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags,
14471c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian        PixelFormat& format)
1448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) { // TODO: take h/w into account
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1456a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1457a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1458a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
14598f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1460a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1464a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1465a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1466a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1467a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1468a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
146996f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Layer> layer = new Layer(this, display, client);
1470f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian    status_t err = layer->setBuffers(w, h, format, flags);
147199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_LIKELY(err != NO_ERROR)) {
1472921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createNormalLayer() failed (%s)", strerror(-err));
1473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        layer.clear();
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1478921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerDim> SurfaceFlinger::createDimLayer(
1479f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian        const sp<Client>& client, DisplayID display,
148096f0819f81293076e652792794a961543e6750d7Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
148296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerDim> layer = new LayerDim(this, display, client);
1483118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return layer;
1484118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1485118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1486921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopiansp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
1487118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        const sp<Client>& client, DisplayID display,
1488118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        uint32_t w, uint32_t h, uint32_t flags)
1489118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
1490118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return layer;
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1494921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid)
14959a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
14969a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    /*
14979a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * called by the window manager, when a surface should be marked for
14989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     * destruction.
14998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber     *
15000aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * The surface is removed from the current and drawing lists, but placed
15010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * in the purgatory queue, so it's not destroyed right-away (we need
15020aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian     * to wait for all client's references to go away first).
15039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian     */
15049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
150548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    status_t err = NAME_NOT_FOUND;
15060aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian    Mutex::Autolock _l(mStateLock);
150796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<LayerBaseClient> layer = client->getLayerUser(sid);
1508b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam
150948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian    if (layer != 0) {
151048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        err = purgatorizeLayer_l(layer);
151148d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        if (err == NO_ERROR) {
151248d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian            setTransactionFlags(eTransactionNeeded);
151348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian        }
15149a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
15159a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
15169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
15179a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
1518921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1520759fdb2ef735422d6b8c65e168fa9d1c24562a86Mathias Agopian    // called by ~ISurface() when all references are gone
1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    sp<LayerBaseClient> l(layer.promote());
1523ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
1524ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        Mutex::Autolock _l(mStateLock);
1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        err = removeLayer_l(l);
1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian        if (err == NAME_NOT_FOUND) {
1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // The surface wasn't in the current list, which means it was
1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // removed already, which means it is in the purgatory,
1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            // and need to be removed from there.
1530ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian            ssize_t idx = mLayerPurgatory.remove(l);
1531e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE_IF(idx < 0,
1532ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                    "layer=%p is not in the purgatory list", l.get());
1533f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian        }
1534e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
1535ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
1536ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
1537ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1540698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
154196f0819f81293076e652792794a961543e6750d7Mathias Agopian        const sp<Client>& client,
1542698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const layer_state_t& s)
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t flags = 0;
1545698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
1546698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    if (layer != 0) {
1547698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const uint32_t what = s.what;
1548698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & ePositionChanged) {
1549698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setPosition(s.x, s.y))
1550698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1551698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1552698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eLayerChanged) {
1553698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1554698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setLayer(s.z)) {
1555698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1556698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1557698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // we need traversal (state changed)
1558698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                // AND transaction (list changed)
1559698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1561698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1562698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eSizeChanged) {
1563698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1564698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1567698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eAlphaChanged) {
1568698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1569698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1570698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1571698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eMatrixChanged) {
1572698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setMatrix(s.matrix))
1573698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1574698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1575698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eTransparentRegionChanged) {
1576698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1577698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1579698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        if (what & eVisibilityChanged) {
1580698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1581698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                flags |= eTraversalNeeded;
1582698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        }
1583f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        if (what & eCropChanged) {
1584f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis            if (layer->setCrop(s.crop))
1585f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis                flags |= eTraversalNeeded;
1586f15a83f5814219c167f87cb8aaea622fc8493499Jamie Gennis        }
15878785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian        if (what & eLayerStackChanged) {
15888785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian            if (layer->setLayerStack(s.layerStack))
15898785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian                flags |= eTraversalNeeded;
15908785578391eacd4192333d7b0ce3afedd7d163e6Mathias Agopian        }
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1592698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    return flags;
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1595b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1596b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1597b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenAcquired() {
15988e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("Screen about to return, flinger = %p", this);
15991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
16008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().acquire();
1601b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    hw.acquireScreen();
160222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    mEventThread->onScreenAcquired();
1603b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // this is a temporary work-around, eventually this should be called
1604b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    // by the power-manager
1605b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
160622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    // from this point on, SF will process updates again
16078acce2046ac7086c3dcfb1fc7c9c39f31de48694Mathias Agopian    repaintEverything();
1608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1610b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopianvoid SurfaceFlinger::onScreenReleased() {
16118e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    ALOGD("About to give-up screen, flinger = %p", this);
16121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: this should be per DisplayHardware
1613b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    if (hw.isScreenAcquired()) {
161422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        mEventThread->onScreenReleased();
1615b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        hw.releaseScreen();
16168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian        getHwComposer().release();
1617b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        // from this point on, SF will stop drawing
1618b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
1619b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1620b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
16218e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::unblank() {
1622b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
1623b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1624b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1625b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
1626b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1627b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenAcquired();
1628b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1629b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1630b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1631b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(this);
1632b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16358e533069e5721e55cb9768e140e16546c3a4a8b6Colin Crossvoid SurfaceFlinger::blank() {
1636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
1637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        SurfaceFlinger* flinger;
1638b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
1639b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
1640b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
1641b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            flinger->onScreenReleased();
1642b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
1643b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
1644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
1645b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(this);
1646b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    postMessageSync(msg);
1647b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
1648b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1649b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
1650b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16531d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    const size_t SIZE = 4096;
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[SIZE];
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
165699b49840d309727678b77403d6cc9f920111623fMathias Agopian
165799b49840d309727678b77403d6cc9f920111623fMathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                IPCThreadState::self()->getCallingUid());
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        result.append(buffer);
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
16659795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
16669795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
16679795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
16689795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
16699795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
16709795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
16729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
16738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber            snprintf(buffer, SIZE,
16749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
16759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
16769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            result.append(buffer);
16779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
16789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
167982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
168082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
168125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
168225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
168325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
168425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
168525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
168625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                listLayersLocked(args, index, result, buffer, SIZE);
168735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
168825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
168925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
169025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
169125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
169282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
169382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                dumpStatsLocked(args, index, result, buffer, SIZE);
169435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
169582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
169625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
169725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
169825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
169925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
170025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                clearStatsLocked(args, index, result, buffer, SIZE);
170135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
170225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
170582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
170682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            dumpAllLocked(result, buffer, SIZE);
170782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
170848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
170982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
171082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
171148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
171282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
171382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
171482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
171582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
171648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
171725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
171825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
171925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
172025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
172125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
172225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
172325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
172425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        snprintf(buffer, SIZE, "%s\n", layer->getName().string());
172525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        result.append(buffer);
172625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
172725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
172825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
172982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
173082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
173182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
173282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
173382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
173482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
173582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
173682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
173748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
173882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
173982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
174082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
174182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
174282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty()) {
174382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            snprintf(buffer, SIZE, "%s\n", layer->getName().string());
174482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            result.append(buffer);
174582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
174782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            layer->dumpStats(result, buffer, SIZE);
174882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
174982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
175082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
1751ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
175225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
175325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        String8& result, char* buffer, size_t SIZE) const
175425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
175525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
175625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
175725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
175825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
175925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
176025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
176125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
176225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
176325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
176425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
176525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
176625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
176725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
176825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
176925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
177025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
177182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpAllLocked(
177282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        String8& result, char* buffer, size_t SIZE) const
177382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
177482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
177582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
177682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
177782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
177882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
177982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1780bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
178182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
178282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
178382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
178482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
178582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
178682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
178782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
178882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
178982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(currentLayers[i]);
179082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->dump(result, buffer, SIZE);
179182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
1792bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
179382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
179482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the layers in the purgatory
179582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
1796ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
179782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t purgatorySize = mLayerPurgatory.size();
179882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
179982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
180082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<purgatorySize ; i++) {
180182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
180282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        layer->shortDump(result, buffer, SIZE);
180382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
18041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
180682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
180782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18081b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
180982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
181082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18111b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
18121b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
181382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GLExtensions& extensions(GLExtensions::getInstance());
181482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
181582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVendor(),
181682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getRenderer(),
181782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            extensions.getVersion());
181882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
1819d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
182082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EGL : %s\n",
18211b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian            eglQueryString(hw.getEGLDisplay(),
182282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    EGL_VERSION_HW_ANDROID));
182382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
182473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian
182582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
182682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
182882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mWormholeRegion.dump(result, "WormholeRegion");
182982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
183082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  orientation=%d, canDraw=%d\n",
183182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mCurrentState.orientation, hw.canDraw());
183282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
183382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE,
183482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
183582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
1836c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
183782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
183882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
1839b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  y-dpi                     : %f\n"
1840b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            "  density                   : %f\n",
184182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
184282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
1843c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
184482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getRefreshRate(),
184582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hw.getDpiX(),
1846b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDpiY(),
1847b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian            hw.getDensity());
184882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
184982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
185182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
185282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  transaction time: %f us\n",
185582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
185682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
185782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
185882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
185982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
186082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
186182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    mEventThread->dump(result, buffer, SIZE);
186282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
186382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
186482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
186582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
18668630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
186782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "h/w composer state:\n");
186882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
186982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
187082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
187182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                    (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
187282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    result.append(buffer);
18733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
187482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
187582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
187682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
187782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
187882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
187982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
188082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    hw.dump(result);
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
1888698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case SET_ORIENTATION:
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
189159119e658a12279e8fff508f8773843de2d90917Mathias Agopian        case TURN_ELECTRON_BEAM_OFF:
18929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        case TURN_ELECTRON_BEAM_ON:
18938e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
18948e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
1899a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
190099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
190199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
1902e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
1903375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1904375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
1905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
19071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
19081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
19091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
19101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
19111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
19121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
19131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
191499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
191599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
1916e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
19171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
19181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
19191b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
19201b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1926b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
192799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
1928375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
1929375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
1930375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
1931e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
1932375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
193701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
193835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
194353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
194453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
194753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
1948cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1949cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
1950cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
1951cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1952cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
19544d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
19554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
19564d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
19574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
195853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
195953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
196053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
196153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
196253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
196353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
1964a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
1965a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
1966a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
1967a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
1968a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
1969a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
197101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
1974b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
197512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
19791b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                const DisplayHardware& hw(getDefaultDisplayHardware());
1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(hw.getPageFlipCount());
1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_ERROR;
1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
19891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: this cannot be bound the default display
19900dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    const Rect bounds(hw.getBounds());
19910dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    setInvalidateRegion(Region(bounds));
199299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
199353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
199453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
19950dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopianvoid SurfaceFlinger::setInvalidateRegion(const Region& reg) {
19960dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
19970dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion = reg;
19980dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
19990dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
20000dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias AgopianRegion SurfaceFlinger::getAndClearInvalidateRegion() {
20010dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Mutex::Autolock _l(mInvalidateLock);
20020dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    Region reg(mInvalidateRegion);
20030dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    mInvalidateRegion.clear();
20040dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian    return reg;
20050dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian}
20060dfb7b73a468698622d6c0423f0d5471a6f5d375Mathias Agopian
200759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
200859119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2009118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
2010118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
2011118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian{
2012118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    Mutex::Autolock _l(mStateLock);
2013118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    return renderScreenToTextureLocked(dpy, textureName, uOut, vOut);
2014118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2015118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
20179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
201859119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
201922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
202022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
202159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
202259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        return INVALID_OPERATION;
202359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
202459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // get screen geometry
20251b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
202659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_w = hw.getWidth();
202759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    const uint32_t hw_h = hw.getHeight();
202859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat u = 1;
202959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLfloat v = 1;
203059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // make sure to clear all GL error flags
203259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
203359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
203459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    // create a FBO
203559119e658a12279e8fff508f8773843de2d90917Mathias Agopian    GLuint name, tname;
203659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenTextures(1, &tname);
203759119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
2038a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2039a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (glGetError() != GL_NO_ERROR) {
2043015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian        while ( glGetError() != GL_NO_ERROR ) ;
204459119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint tw = (2 << (31 - clz(hw_w)));
204559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        GLint th = (2 << (31 - clz(hw_h)));
20469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
20479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
204859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        u = GLfloat(hw_w) / tw;
204959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        v = GLfloat(hw_h) / th;
205059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
205159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glGenFramebuffersOES(1, &name);
205259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
20539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
20549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
205559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // redraw the screen entirely...
2057c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_EXTERNAL_OES);
2058c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_TEXTURE_2D);
20599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClearColor(0,0,0,1);
20609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2061a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2062a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
20633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
20649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const size_t count = layers.size();
20659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
20669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const sp<LayerBase>& layer(layers[i]);
20671b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        layer->drawForSreenShot(hw);
20689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
206959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2070118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    hw.compositionComplete();
2071118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
20729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // back to main framebuffer
20739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
20749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteFramebuffersOES(1, &name);
207559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *textureName = tname;
20779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *uOut = u;
20789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    *vOut = v;
20799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
20809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
208159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
20829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
208359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2084ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianclass VSyncWaiter {
2085ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    DisplayEventReceiver::Event buffer[4];
2086ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<Looper> looper;
2087ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<IDisplayEventConnection> events;
2088ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    sp<BitTube> eventTube;
2089ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopianpublic:
2090ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter(const sp<EventThread>& eventThread) {
2091ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper = new Looper(true);
2092ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events = eventThread->createEventConnection();
2093ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        eventTube = events->getDataChannel();
2094ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->addFd(eventTube->getFd(), 0, ALOOPER_EVENT_INPUT, 0, 0);
2095ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2096ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2097ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2098ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    void wait() {
2099ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        ssize_t n;
2100ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2101ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        looper->pollOnce(-1);
2102ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // we don't handle any errors here, it doesn't matter
2103ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // and we don't want to take the risk to get stuck.
2104ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2105ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // drain the events...
2106ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        while ((n = DisplayEventReceiver::getEvents(
2107ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian                eventTube, buffer, 4)) > 0) ;
2108ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2109ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        events->requestNextVsync();
2110ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    }
2111ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian};
2112ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
21139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
21149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
21159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
21161b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
21179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
21189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
2119a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const Region screenBounds(hw.getBounds());
212059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
21229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
2123118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    status_t result = renderScreenToTextureLocked(0, &tname, &u, &v);
21249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
21259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
21269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
212759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
21289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
2129a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    const GLfloat texCoords[4][2] = { {0,0}, {0,v}, {u,v}, {u,0} };
21309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
21319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
21329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
21339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2134b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2135b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
21379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
21389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
21399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2140ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    /*
2141ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     * Texture coordinate mapping
2142ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2143ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *                 u
2144ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    1 +----------+---+
2145ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     |    |   |  image is inverted
2146ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |     V    |   |  w.r.t. the texture
2147ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *  1-v +----------+   |  coordinates
2148ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2149ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2150ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      |              |
2151ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *    0 +--------------+
2152ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *      0              1
2153ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     *
2154ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian     */
2155ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
21569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
21579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
21589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
21609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
21619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
21629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
21649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
21659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
21669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
21709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21719daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21729daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
21739daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
21749daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
21779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
21789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2180ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2181ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2182ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2183ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
21849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
21859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
21869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
21879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
21889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
21899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
21909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
21919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
219259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
21939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
21949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
21959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
21969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
21979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
2198ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[0] = x;         vtx[1] = y;
2199ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
2200ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
2201ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
22029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
22039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
22049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2205ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2206ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // the full animation is 24 frames
2208ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    char value[PROPERTY_VALUE_MAX];
2209ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    property_get("debug.sf.electron_frames", value, "24");
2210ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    int nbFrames = (atoi(value) + 1) >> 1;
2211ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian    if (nbFrames <= 0) // just in case
2212ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        nbFrames = 24;
2213ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian
22149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
22159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
22169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
22179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
2219a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
2220a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_TEXTURE);
2221a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2222a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glMatrixMode(GL_MODELVIEW);
2223a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian    glLoadIdentity();
2224a9040d0eefa34a78ca68b6e7901e1703e74aeb7cMathias Agopian
22259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
22269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
22279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
22299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
22309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
22319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
22329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2233ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2234ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2235ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
22379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,1,1,1);
22389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
224059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
22419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
22429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
22439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
22449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
22479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
22489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
22499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
22529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
22539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
22549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the white highlight (we use the last vertices)
225759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glDisable(GL_TEXTURE_2D);
225859119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
22599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(vg, vg, vg, 1);
22609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
22659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
22669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
22679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=0 ; i<nbFrames ; i++) {
22699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
22709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2271ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2272ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2273ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2274ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
22759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
22769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
22779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
22789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
22799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
22809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
22829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
22839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDeleteTextures(1, &tname);
2284a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2285c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
22869daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
22879daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
22889daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22899daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
22909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
22919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    status_t result = PERMISSION_DENIED;
22929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
22949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return INVALID_OPERATION;
22959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
22979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    // get screen geometry
22981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDefaultDisplayHardware());
22999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_w = hw.getWidth();
23009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const uint32_t hw_h = hw.getHeight();
23019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const Region screenBounds(hw.bounds());
23029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat u, v;
23049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLuint tname;
23059daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    result = renderScreenToTextureLocked(0, &tname, &u, &v);
23069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (result != NO_ERROR) {
23079daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return result;
23089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    GLfloat vtx[8];
23119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
23129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
23139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
23149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
23159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2316b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2317b1d1c6d4c2eb942e18a59a8cdf1c7c4f0f03ef1bMichael I. Gold    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
23189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
23199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
23209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glVertexPointer(2, GL_FLOAT, 0, vtx);
23219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class s_curve_interpolator {
23239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float nbFrames, s, v;
23249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        s_curve_interpolator(int nbFrames, float s)
23269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : nbFrames(1.0f / (nbFrames-1)), s(s),
23279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian          v(1.0f + expf(-s + 0.5f*s)) {
23289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float operator()(int f) {
23309daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const float x = f * nbFrames;
23319daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
23329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class v_stretch {
23369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        v_stretch(uint32_t hw_w, uint32_t hw_h)
23399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
234059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
23419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w + (hw_w * v);
23439daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = hw_h - (hw_h * v);
23449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23529daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23539daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class h_stretch {
23549daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const GLfloat hw_w, hw_h;
23559daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
23569daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        h_stretch(uint32_t hw_w, uint32_t hw_h)
23579daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        : hw_w(hw_w), hw_h(hw_h) {
23589daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23599daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        void operator()(GLfloat* vtx, float v) {
23609daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat w = hw_w - (hw_w * v);
23619daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat h = 1.0f;
23629daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat x = (hw_w - w) * 0.5f;
23639daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            const GLfloat y = (hw_h - h) * 0.5f;
23649daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[0] = x;         vtx[1] = y;
23659daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[2] = x;         vtx[3] = y + h;
23669daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[4] = x + w;     vtx[5] = y + h;
23679daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            vtx[6] = x + w;     vtx[7] = y;
23689daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
23699daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
23709daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2371ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian    VSyncWaiter vsync(mEventThread);
2372ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2373a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    // the full animation is 12 frames
2374a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    int nbFrames = 8;
23759daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itr(nbFrames, 7.5f);
23769daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itg(nbFrames, 8.0f);
23779daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    s_curve_interpolator itb(nbFrames, 8.5f);
23789daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
23799daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    h_stretch hverts(hw_w, hw_h);
23809daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_BLEND);
23819daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisable(GL_TEXTURE_2D);
23829daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
23839daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
23849daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float v = itg(i);
23859daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hverts(vtx, v);
2386ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
2387ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2388ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2389ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
23909daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
23919daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColor4f(1-v, 1-v, 1-v, 1);
23929daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
23939daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
23949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
23959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2396a6546e5af4ce0cff01cd13605fc3eb16325feac3Mathias Agopian    nbFrames = 4;
23979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    v_stretch vverts(hw_w, hw_h);
23989daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glEnable(GL_BLEND);
23999daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glBlendFunc(GL_ONE, GL_ONE);
24009daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    for (int i=nbFrames-1 ; i>=0 ; i--) {
24019daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        float x, y, w, h;
24029daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vr = itr(i);
24039daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vg = itg(i);
24049daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        const float vb = itb(i);
240559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2406ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        // wait for vsync
2407ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian        vsync.wait();
2408ed9807bd7dbd4863841e251138392c54755eb394Mathias Agopian
24099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // clear screen
241059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        glColorMask(1,1,1,1);
24119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
24129daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glEnable(GL_TEXTURE_2D);
24139daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24149daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the red plane
24159daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vr);
24169daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(1,0,0,1);
24179daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24189daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24199daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the green plane
24209daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vg);
24219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,1,0,1);
24229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // draw the blue plane
24259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        vverts(vtx, vb);
24269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glColorMask(0,0,1,1);
24279daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
24289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        hw.flip(screenBounds);
243059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
243159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glColorMask(1,1,1,1);
24339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
243459119e658a12279e8fff508f8773843de2d90917Mathias Agopian    glDeleteTextures(1, &tname);
2435a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    glDisable(GL_TEXTURE_2D);
2436c492e67810814bf86301abffe1d31598b775cf45Mathias Agopian    glDisable(GL_BLEND);
243759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
24389daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
24399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
24409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
24429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2443abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
24449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
244522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    ATRACE_CALL();
244622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
24471b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
24489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (!hw.canDraw()) {
24499daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already off
24509daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
24519daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
24527ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
24537ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // turn off hwc while we're doing the animation
24548630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    getHwComposer().disable();
24557ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    // and make sure to turn it back on (if needed) next time we compose
24567ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian    invalidateHwcGeometry();
24577ee4cd5556cef1878e1d4729f1b389f186311027Mathias Agopian
2458abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2459abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOffAnimationImplLocked();
2460abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2461abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2462abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    // always clear the whole screen at the end of the animation
2463abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClearColor(0,0,0,1);
2464abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
2465abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    hw.flip( Region(hw.bounds()) );
2466abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian
2467015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
246859119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
246959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
247059119e658a12279e8fff508f8773843de2d90917Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
247159119e658a12279e8fff508f8773843de2d90917Mathias Agopian{
247259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    class MessageTurnElectronBeamOff : public MessageBase {
247359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        SurfaceFlinger* flinger;
2474abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
247559119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t result;
247659119e658a12279e8fff508f8773843de2d90917Mathias Agopian    public:
2477abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
2478abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
247959119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248059119e658a12279e8fff508f8773843de2d90917Mathias Agopian        status_t getResult() const {
248159119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return result;
248259119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        virtual bool handler() {
248459119e658a12279e8fff508f8773843de2d90917Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2485abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOffImplLocked(mode);
248659119e658a12279e8fff508f8773843de2d90917Mathias Agopian            return true;
248759119e658a12279e8fff508f8773843de2d90917Mathias Agopian        }
248859119e658a12279e8fff508f8773843de2d90917Mathias Agopian    };
248959119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2490abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
249159119e658a12279e8fff508f8773843de2d90917Mathias Agopian    status_t res = postMessageSync(msg);
249259119e658a12279e8fff508f8773843de2d90917Mathias Agopian    if (res == NO_ERROR) {
249359119e658a12279e8fff508f8773843de2d90917Mathias Agopian        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
24949daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
24959daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // work-around: when the power-manager calls us we activate the
24969daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // animation. eventually, the "on" animation will be called
24979daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // by the power-manager itself
2498abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        mElectronBeamAnimationMode = mode;
249959119e658a12279e8fff508f8773843de2d90917Mathias Agopian    }
250059119e658a12279e8fff508f8773843de2d90917Mathias Agopian    return res;
250159119e658a12279e8fff508f8773843de2d90917Mathias Agopian}
250259119e658a12279e8fff508f8773843de2d90917Mathias Agopian
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2505abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
25069daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    DisplayHardware& hw(const_cast<DisplayHardware&>(getDefaultDisplayHardware()));
25089daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    if (hw.canDraw()) {
25099daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        // we're already on
25109daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        return NO_ERROR;
25119daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    }
2512abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
2513abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        electronBeamOnAnimationImplLocked();
2514abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    }
2515a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2516a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    // make sure to redraw the whole screen when the animation is done
2517a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian    mDirtyRegion.set(hw.bounds());
251899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
2519a7f0373533e590fdca1400f90e6657ebb2dd5f17Mathias Agopian
2520015fb3fb41ffe04475ab2b604cc30cc1c031815aMathias Agopian    return NO_ERROR;
25219daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25229daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25239daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopianstatus_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
25249daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian{
25259daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    class MessageTurnElectronBeamOn : public MessageBase {
25269daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        SurfaceFlinger* flinger;
2527abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        int32_t mode;
25289daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t result;
25299daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    public:
2530abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
2531abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
25329daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25339daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        status_t getResult() const {
25349daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return result;
25359daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25369daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        virtual bool handler() {
25379daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
2538abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian            result = flinger->turnElectronBeamOnImplLocked(mode);
25399daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian            return true;
25409daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian        }
25419daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    };
25429daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
2543abd671a08a41519a7ab3d438a500efe0ef0bfc1dMathias Agopian    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
25449daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian    return NO_ERROR;
25459daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian}
25469daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
25479daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian// ---------------------------------------------------------------------------
25489daa5c9b9dd286cbbf5d43f7e45a5e9e4048e855Mathias Agopian
254974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
255074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        sp<IMemoryHeap>* heap,
255174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* w, uint32_t* h, PixelFormat* f,
2552bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2553bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
255474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2555fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2556fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
255774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    status_t result = PERMISSION_DENIED;
255874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
255974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // only one display supported for now
25603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
256174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject()) {
256574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return INVALID_OPERATION;
25663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
256774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
256874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // get screen geometry
25691b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    const DisplayHardware& hw(getDisplayHardware(dpy));
257074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_w = hw.getWidth();
257174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const uint32_t hw_h = hw.getHeight();
257274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25733b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    // if we have secure windows on this display, never allow the screen capture
25743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if (hw.getSecureLayerVisible()) {
25753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        return PERMISSION_DENIED;
25763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
25773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
25783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    if ((sw > hw_w) || (sh > hw_h)) {
257974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        return BAD_VALUE;
25803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
258174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
258274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sw = (!sw) ? hw_w : sw;
258374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    sh = (!sh) ? hw_h : sh;
258474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    const size_t size = sw * sh * 4;
258574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
25869d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    //ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
25871c71a47a6db679a3212f0c99e14f330d6da500faMathias Agopian    //        sw, sh, minLayerZ, maxLayerZ);
2588c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
258974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // make sure to clear all GL error flags
259074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    while ( glGetError() != GL_NO_ERROR ) ;
259174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
259274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // create a FBO
259374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLuint name, tname;
259474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenRenderbuffersOES(1, &tname);
259574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
259674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
2597fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
259874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glGenFramebuffersOES(1, &name);
259974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
260074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
260174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
260274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
2604c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
260574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
260674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
260774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // invert everything, b/c glReadPixel() below will invert the FB
260874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, sw, sh);
260974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
261074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPushMatrix();
261174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glLoadIdentity();
2612ffcf4657718831edecb6ff2ed1b45ac8bf8b9a58Mathias Agopian        glOrthof(0, hw_w, hw_h, 0, 0, 1);
261374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
261474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
261574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // redraw the screen entirely...
261674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClearColor(0,0,0,1);
261774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glClear(GL_COLOR_BUFFER_BIT);
2618f653b897a449e10d6cbfb6e0812f7b0bb02d6482Mathias Agopian
26199575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const LayerVector& layers(mDrawingState.layersSortedByZ);
26209575f60722f7a4f54384fe0be6938a8de48dc23aJamie Gennis        const size_t count = layers.size();
262174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        for (size_t i=0 ; i<count ; ++i) {
262274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            const sp<LayerBase>& layer(layers[i]);
2623b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            const uint32_t flags = layer->drawingState().flags;
2624b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian            if (!(flags & ISurfaceComposer::eLayerHidden)) {
2625b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                const uint32_t z = layer->drawingState().z;
2626b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                if (z >= minLayerZ && z <= maxLayerZ) {
26271b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian                    layer->drawForSreenShot(hw);
2628b0610335d745718f5ee54f15ef1a492921d759f4Mathias Agopian                }
2629bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            }
263074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
263174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
263274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        // check for errors and return screen capture
263374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        if (glGetError() != GL_NO_ERROR) {
263474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // error while rendering
263574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = INVALID_OPERATION;
263674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        } else {
263774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // allocate shared memory large enough to hold the
263874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            // screen capture
263974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            sp<MemoryHeapBase> base(
264074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    new MemoryHeapBase(size, 0, "screen-capture") );
264174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            void* const ptr = base->getBase();
264274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            if (ptr) {
264374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                // capture the screen with glReadPixels()
2644fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
264574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
264674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                if (glGetError() == GL_NO_ERROR) {
264774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *heap = base;
264874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *w = sw;
264974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *h = sh;
265074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    *f = PIXEL_FORMAT_RGBA_8888;
265174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                    result = NO_ERROR;
265274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
265374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            } else {
265474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                result = NO_MEMORY;
265574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
265674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
265774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glViewport(0, 0, hw_w, hw_h);
265874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_PROJECTION);
265974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glPopMatrix();
266074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        glMatrixMode(GL_MODELVIEW);
266174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    } else {
266274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        result = BAD_VALUE;
266374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
266474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
266574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    // release FBO resources
266674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
266774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteRenderbuffersOES(1, &tname);
266874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    glDeleteFramebuffersOES(1, &name);
2669e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
2670e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian    hw.compositionComplete();
2671e6f0984361f634ff36bc0ad1c2d45f4554619ac8Mathias Agopian
26729d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block    // ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
2673c1d1b0d9b74d8f55346d0b84f369e48ecf2e0d33Mathias Agopian
267474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
267574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
267674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
267774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
26781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopianstatus_t SurfaceFlinger::captureScreen(DisplayID dpy,
26791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap,
268074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t* width, uint32_t* height, PixelFormat* format,
2681bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t sw, uint32_t sh,
2682bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian{
26841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    // only one display supported for now
268599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
26861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return BAD_VALUE;
26871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (!GLExtensions::getInstance().haveFramebufferObject())
26891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        return INVALID_OPERATION;
26901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
26911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    class MessageCaptureScreen : public MessageBase {
26921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        SurfaceFlinger* flinger;
26931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        DisplayID dpy;
26941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        sp<IMemoryHeap>* heap;
26951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* w;
26961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        uint32_t* h;
26971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        PixelFormat* f;
269874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sw;
269974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        uint32_t sh;
2700bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t minLayerZ;
2701bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian        uint32_t maxLayerZ;
27021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t result;
27031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    public:
27041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
270574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
2706bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t sw, uint32_t sh,
2707bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
27081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            : flinger(flinger), dpy(dpy),
2709bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
2710bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2711bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian              result(PERMISSION_DENIED)
27121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27131b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        status_t getResult() const {
27151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return result;
27161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        virtual bool handler() {
27181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
271974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            result = flinger->captureScreenImplLocked(dpy,
2720bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
27211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            return true;
27221b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    };
27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
2726bf2c6a6c8f1df40ac94e28b948754bb9739daacaMathias Agopian            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    status_t res = postMessageSync(msg);
27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    if (res == NO_ERROR) {
27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    }
27311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian    return res;
27321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian}
27331b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
27341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
27351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2736921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2737921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2738921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2739921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
2740921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : SortedVector<sp<LayerBase> >(rhs) {
2741921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2742921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2743921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2744921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2746921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
2747921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
2748921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    // sort layers by Z order
2749921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t lz = l->currentState().z;
2750921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    uint32_t rz = r->currentState().z;
2751921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    // then by sequence, so we get a stable ordering
2752921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence);
2753921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2754921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2755921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
2756921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2757921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::State::State()
2758921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    : orientation(ISurfaceComposer::eOrientationDefault),
2759921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian      orientationFlags(0) {
2760b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
27617303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
2762b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
276396f0819f81293076e652792794a961543e6750d7Mathias Agopian
27649a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::GraphicBufferAlloc() {}
27659a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27669a78c90cd46b2a3bd637b056873149d3b94384b4Jamie GennisGraphicBufferAlloc::~GraphicBufferAlloc() {}
27679a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27689a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
2769d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        PixelFormat format, uint32_t usage, status_t* error) {
27709a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
27719a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    status_t err = graphicBuffer->initCheck();
2772d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian    *error = err;
2773a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    if (err != 0 || graphicBuffer->handle == 0) {
2774d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        if (err == NO_MEMORY) {
2775d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian            GraphicBuffer::dumpAllocationsToSystemLog();
2776d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        }
2777e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
2778a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian             "failed (%s), handle=%p",
2779a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian                w, h, strerror(-err), graphicBuffer->handle);
27809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis        return 0;
27819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    }
27829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return graphicBuffer;
27839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
27849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
27859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis// ---------------------------------------------------------------------------
27869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
2788