SurfaceFlinger.cpp revision 7143316af216fa92c31a60d4407b707637382da1
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>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
41e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
42392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
47d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
48cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
521c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
55ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6090ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
610f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
62faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
63d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
64d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
70a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
74ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
75875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
77875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
81fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
82fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
86ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
87ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
89faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
90faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This works around the lack of support for the sync framework on some
91faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// devices.
92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const bool runningWithoutSyncFramework = true;
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#else
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const bool runningWithoutSyncFramework = false;
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#endif
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
119faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12999b49840d309727678b77403d6cc9f920111623fMathias Agopian
13099b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
13199b49840d309727678b77403d6cc9f920111623fMathias Agopian
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1334f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
137076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
139875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
142a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
1434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1458afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
147a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
152ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
153faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
154948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
1559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mDaltonize(false),
1569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mHasColorMatrix(false)
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1628afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
163b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
16450210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
165b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1688afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1698afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
17263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
17363f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
17463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
177c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
178c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
18299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
18399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
18499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
18599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
188a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
189a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
190a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who)
19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
19813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
201a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2047e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
20796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
20896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
20996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
21096f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
216dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
2353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
2368dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
237dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
268692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
269692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
270692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2739e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
276e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
277692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
290a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2913330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
297921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
301a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
302a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
303a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3123f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
318921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
320921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
322faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
323faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) :
3250a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mPhaseOffset(phaseOffset),
3270a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3280a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mDispSync(dispSync) {}
329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // Do NOT lock the mutex here so as to avoid any mutex ordering issues
334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // with locking it in the onDispSyncEvent callback.
335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3360a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            status_t err = mDispSync->addEventListener(mPhaseOffset,
337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            ATRACE_INT("VsyncOn", 1);
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            ATRACE_INT("VsyncOn", 0);
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        Mutex::Autolock lock(mMutex);
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            Mutex::Autolock lock(mMutex);
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
3670a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
3680a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                ATRACE_INT("VSYNC", mValue);
3690a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
3790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const nsecs_t mPhaseOffset;
3800a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
3810a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex mMutex;
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
391b65f32ebe2c86869b07ac1c986660dfb2187b7d3Jesse Hall    status_t err;
392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    Mutex::Autolock _l(mStateLock);
393692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
39634a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
402b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
403875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // get a RenderEngine for the given display / config (can't fail)
40405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
407875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
411da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4139e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
415f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        // set-up the displays that are already connected
4169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            // All non-virtual displays are currently considered secure.
418dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            bool isSecure = true;
419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked(type);
420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            wp<IBinder> token = mBuiltinDisplays[i];
421692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
422db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian            sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
423db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
42419e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall            int32_t hwcId = allocateHwcDisplayId(type);
425f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
42619e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
427db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    fbs, bq,
42805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                    mRenderEngine->getEGLConfig());
429f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
430c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
431f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
432f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
433c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                ALOGD("marking display %d as acquired/unblanked", i);
434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                hw->acquireScreen();
435f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
439cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
440a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // make the GLContext current so that we can create textures when creating Layers
441a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // (which may happens before we render something)
442a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
443a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
444028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
4450a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4460a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            vsyncPhaseOffsetNs, true);
447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mEventThread = new EventThread(vsyncSrc);
4480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            sfVsyncPhaseOffsetNs, false);
4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mSFEventThread = new EventThread(sfVsyncSrc);
4510a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mEventQueue.setEventThread(mSFEventThread);
452028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
453d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
454d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
455d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
456faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    // set a fake vsync period if there is no HWComposer
457faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mHwc->initCheck() != NO_ERROR) {
458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.setPeriod(16666667);
459faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
460faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
46192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
46292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4638630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
46413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
46513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
46613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
467a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
468a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4729e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
4733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
476a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
477a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
478a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
479a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
480a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
482875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
483875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
484a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
485a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
486875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
491d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
492582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
4932adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
4952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
4966710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
4999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
500692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5019e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5031604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5041604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5051604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5061604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5071604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5081604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5091604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
510c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    const HWComposer& hwc(getHwComposer());
5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float xdpi = hwc.getDpiX(type);
5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    float ydpi = hwc.getDpiY(type);
5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5321604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5331604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type == DisplayDevice::DISPLAY_PRIMARY) {
5341604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // The density of the device is provided by a build property
5351604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        float density = Density::getBuildDensity() / 160.0f;
5361604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (density == 0) {
5371604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // the build doesn't provide a density -- this is wrong!
5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // use xdpi instead
5391604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            ALOGE("ro.sf.lcd_density must be defined as a build property");
5401604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density = xdpi / 160.0f;
5411604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5421604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        if (Density::getEmuDensity()) {
5431604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            // if "qemu.sf.lcd_density" is specified, it overrides everything
5441604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            xdpi = ydpi = density = Density::getEmuDensity();
5451604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            density /= 160.0f;
5461604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5471604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = density;
5481604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5491604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: this needs to go away (currently needed only by webkit)
5501604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5511604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = hw->getOrientation();
5521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    } else {
5531604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        // TODO: where should this value come from?
5541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        static const int TV_DENSITY = 213;
5551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->density = TV_DENSITY / 160.0f;
5561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        info->orientation = 0;
5578b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
5588b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->w = hwc.getWidth(type);
5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->h = hwc.getHeight(type);
5618b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->xdpi = xdpi;
5628b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    info->ydpi = ydpi;
5631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    info->fps = float(1e9 / hwc.getRefreshPeriod(type));
564dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
565dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    // All non-virtual displays are currently considered secure.
566dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info->secure = true;
567dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
568888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
569c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
570c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
571d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
572d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
573d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
5748aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
575bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
576bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
57999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
58099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
58199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
58299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
58399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
58499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
58599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
58699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
58999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        nsecs_t reltime, uint32_t flags) {
60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6094f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
6104f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
6114f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
6124f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
615faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
616faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
617948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
618faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
619d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
620d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
621faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
62243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
623faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
624faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
625948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
626faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
627faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
628948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
629948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
630948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
631948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
632948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
633948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
634948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
635faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
636faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
637faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
638faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
639faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
640faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
641faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
642faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
643d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
644d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
645faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
646faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
647faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
648faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
649948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
650faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
651faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
652d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
653d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
654faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
655faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
656faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
657948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
658948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
659948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
660faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
661faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
662faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
663d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
664faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
665d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
666d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
667d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
668d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
669faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
670148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
671d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
672d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
673d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
674d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
675d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
676d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
677148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
678148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
679148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
680148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
681148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
682148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
683148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
684148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
685148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
686148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
6879e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
6889e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6899e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
690692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
691692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
6929e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
693692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
694692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
6959e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
6969e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
6979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
6989e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
6993ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
7008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
70281cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
703faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
70481cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
7058630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7068630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
7081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
7109eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    case MessageQueue::TRANSACTION:
7119eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        handleMessageTransaction();
7129eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        break;
7134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
7154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
7164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
7174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
7194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
7204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
725e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
7264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
72787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
7284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
73387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
7344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
7353a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
7364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
755cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
756cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
757cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
758cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
759cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
760cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
761cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
762cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
7643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
7653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
7663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
767cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
768da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
770cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
771cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
773cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
775cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
776cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
777cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
778bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
779bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
780bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
781bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
782bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
783bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
784cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
785cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
786cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
788cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
7891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
7901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
791cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
7921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
794cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
795cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
796cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
800a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
8031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
8041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
8061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
8084b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
809faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
810faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
811faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
812faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
813faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
814faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
815faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
816948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
817faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
818faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
819faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
820faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (runningWithoutSyncFramework) {
821faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
822faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (hw->isScreenAcquired()) {
823faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
824faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
825faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
826faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
8274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
8284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
8294b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
830a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
8314b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
8324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
8334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
8344b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
8354b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
8364b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
8374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
8384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
8394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
84452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
84687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
84787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
848ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
8491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
85092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
851ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
852ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
8544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
8557e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
8567e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
857ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            if (hw->canDraw()) {
8581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
859ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
8607e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
8611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
862ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
8631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
8641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
865ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
866a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
867a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
868a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
869a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
870ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
871ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
87287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
87387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
8743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
8754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
8767e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
8777e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
8787e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
8793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
8803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
8823b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
884028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
8857143316af216fa92c31a60d4407b707637382da1Dan Stoza        bool mustRecompose =
8867143316af216fa92c31a60d4407b707637382da1Dan Stoza                !(mDisplays[dpy]->getDirtyRegion(false).isEmpty());
8877143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
888028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
889028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
89052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
89152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
89252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
893a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
894a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
895a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
896a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
897a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
898a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
900a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
901a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
902a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
903a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
904a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
905a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
907a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
9089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
909a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
910a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
911a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
912a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
913a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
914a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
915a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
916a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
917a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
91892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
920e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
921e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
923cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
924e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
925a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
926a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
927a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
928a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
929a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
930a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
931a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
93213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
933a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
9341e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
93552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
93687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
937a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
93852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
93952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
94038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
94138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
94238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
94338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
94438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
94552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
946cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
94752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
948cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
949cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
95052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
95192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
953cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        if (hw->canDraw()) {
954cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
955cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
95602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
95702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
95802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
95902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
96387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
96452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
9654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
9664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
96752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
972841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
973b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
974a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
975a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
976c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
97752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
978ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
9792a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
9802a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
9812a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
9822a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
983875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
9842a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
985e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
98652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
98752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
9886da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
9896da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
9906da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
9916da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
9926da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
9936da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
99492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
997da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
99852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
999e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1000e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
10011e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
10021e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
100352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1004d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
100552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1006cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
100752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1008d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
100952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1010ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1011e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1012e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1013a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1014a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
10156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
10166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
10176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
10186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
10196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1024841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1025841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
10267cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
10277cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
10287cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
10297cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
10307cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
10317cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1032ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1033ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1034ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1035ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1036ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1037ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1038ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1039ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1040ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1041ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1042e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
104387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1044ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1045ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1046ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1047ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1048ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
10493d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
10523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
10533d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
106313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
10743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
107892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
107992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
108092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1081e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1082e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
108392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
108592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
108693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
108792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
108892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
108992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
109092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
109192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
109292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
109592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
10963ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
109727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
109827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
109927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
110002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1101875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
110202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
110302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
110402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
11059e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
11067adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
110702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
110892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
110992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
111092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
111192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
111292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1113e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
11143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1115111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1116e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
111793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
111893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
111993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
112002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
112102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
112202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
112393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
112493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
112593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
112693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
112793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
112892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
112993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
113193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
113293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
113393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
113493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
113500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
113600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
113700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
113800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
113900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
11404fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
114193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
114292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
114392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
114492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
114592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
114692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
114792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
114892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1149e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1150e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1151cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
115299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1153db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1154db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
1155db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
115602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
115799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
115802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
115902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
116002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
116199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1162db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
116302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hwcDisplayId = allocateHwcDisplayId(state.type);
1164db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1165db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                    *mHwc, hwcDisplayId, state.surface, bq,
116699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                                    state.displayName);
1167db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1168db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
1169db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            if (hwcDisplayId >= 0) {
1170db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                producer = vds;
1171db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            } else {
1172db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                // There won't be any interaction with HWC for this virtual display,
1173db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                // so the GLES driver can pass buffers directly to the sink.
1174db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                producer = state.surface;
1175db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            }
117699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
117799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1178cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1179cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1180cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1181cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
118202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1183cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1184cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1185db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                        dispSurface = new FramebufferSurface(*mHwc, state.type, bq);
1186db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                        producer = bq;
1187cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1188cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1189cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
119099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1191cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
119219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
119319e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
119405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
119505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1196cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1197cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
11984fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
11998dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1200cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
12011c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
12021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
12031c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
12041c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
12051c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
12061c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
12071c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
12087adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
12091c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
121093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
121192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
121292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
12143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
12178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
12188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
12198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
12208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
12228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
12238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
12258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
12268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
12278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
12298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
12308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
12328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
12338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
12348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
12358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
12378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
12388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
12398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
12408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
12418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
124213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
12431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
12448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
12458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
12468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
12478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
12488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
12498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
12508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
12528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
12538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
12548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
12558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
125691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
12578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
12588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
12598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
12608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
12618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
126291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
126391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
126491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
126591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
126691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
126791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
126891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
126991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
12708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
127191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
12728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
12738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
12748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
12758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
12763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
12773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
12783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
12811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
12823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
12833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
12843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
12853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
12863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
12873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
12883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
12893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
12903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
12911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
12923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
12931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
12943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
12953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
12963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
12973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
12983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
12991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
13001501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
13011501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
13021501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
13030aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
13084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
13094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
13104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
13114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
13124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
13134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
13144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
13154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
13164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
13174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
13184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
13204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
13214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
13224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
13234b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
13244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
13252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
13262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
13274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
133187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
133287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1334841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1335841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
134413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
13471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
135087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
135187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
135287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1353ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1354ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1355ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1357ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1358ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1359ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1360ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1361ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1362ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1363ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1365ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1366ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1367ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1368ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1369ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1371ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1372a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1373a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1374a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1375a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1376a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1377a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1378a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1379a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1380a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1381a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1382ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1383ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1384da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
13854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
13865219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1388ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1389ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1390ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
13914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
13924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
13934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
13944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
13952ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
13964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
13974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
13984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1399a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
14004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
14014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
14022ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
14034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1404ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1406ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
14074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1408ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1409ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1410ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1411ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1412ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1416ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1417ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1418ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1419ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1420ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1421ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
14304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1433a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1434ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1435ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1436ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1437ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1438ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1439ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1440ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1441ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1442ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1443ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1444a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1445ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
14464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
14474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1448ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1449ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
145487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1456ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
14588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1459a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1462a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1463a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
147087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
147192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
14744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
147592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
147692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
147787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
147887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
147987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
14814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
148299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
14834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
14841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
14851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
14864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
14871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
148887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
14891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
149087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
14914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
14924da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
14933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1496ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1497ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1498ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1499ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1500ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
150199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1502cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
150387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15057143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
15067143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
15077143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
15087143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
15097143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
15107143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
15117143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
15127143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
15137143316af216fa92c31a60d4407b707637382da1Dan Stoza
151487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
151587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1516b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
15174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
15200f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
152129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
152229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
152329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
15244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
152729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1528df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
152995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
15300f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
15314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
153329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
15344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
15354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15399c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
1540ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1541ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1542ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
15439c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
15449c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
15459c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
15469c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
15479c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        engine.beginGroup(colorMatrix);
1548ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1549ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        engine.endGroup();
1550ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
15534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1554da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1555da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1556da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1559cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
156285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
15638630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
15641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
15651e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1566a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1567d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
156885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1569875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1570c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1571c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
1572c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            return;
1573c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1574a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1575a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
157685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1577e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1578b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1579b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1580b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
15813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1582b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
15833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1584b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1585766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1586766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1587766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1588766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1589766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1590766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1591766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1592766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1593766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1594766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1595766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1596766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1597766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1598766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1599b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
160087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1601b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
160255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1603b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1604a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1605f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1606766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1607766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1608f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1609f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1610f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1611766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1612f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1613f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1614f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1615f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
16163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1617f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
16183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
16193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
16203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1621f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1622f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
162385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
16244b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
162585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
162685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
162785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
16284b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
163085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
163185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
163285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
163385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
163485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
16364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
163785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
163885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
163985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1640ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
164185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
164285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
16434125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
164485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1645cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1646cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1647cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1648cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
164985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
165085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
165185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1652cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
165385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1654a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1655da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1656da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1657da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
1658da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i);
1659da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1660da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1662a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
166385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
166485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
166585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
166685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
166785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
166813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
166985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
167085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
167185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
167285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
167385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
16744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
16754b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1676f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1677f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
16783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
168255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
16833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
16843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1687ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client,
1688ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
16896710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
169013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
16911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
169296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
1693ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
16944f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
169596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1696921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1697921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
16986710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    mGraphicBufferProducerList.add(gbc->asBinder());
169996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
170096f0819f81293076e652792794a961543e6750d7Mathias Agopian
17013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
170296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
170313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
17056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
1706076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
17076710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) {
1714dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1715dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1716dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
17173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
172499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17298b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
17308b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
17318b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
17328b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
17338b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
17347c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
1735698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
173628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1737e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
17382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
17392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
17402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
17412d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
17427c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
17432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
17442d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
17457c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
17467c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
17477c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
17482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
17492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
17502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
17512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
17522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
17532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
1754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1755e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1756e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1757e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1758b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1759b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1760e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1761698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1762698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1763d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
1764d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
1765d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
1766d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
1767d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
1768d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
1769d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
1770d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
1771d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            sp<IBinder> binder = s.client->asBinder();
1772d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
1773d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
1774d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
1775d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
1776d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
1777d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
1778d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
1779d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
1780698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1781386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
178228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1783386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
178428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1785698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1786386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1787386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1788386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
17892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
17902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
17912d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
17922d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
1793386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
17942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
1795386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1796386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1797386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1798386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
17992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
18002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
1801386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1802386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1803cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
18099a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
18109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
18119a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
18129a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
1813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
18149a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
18153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1828e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
182900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1833e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1834e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
185213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1870e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
18874125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if ((what & layer_state_t::eVisibilityChanged) ||
18884125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                (what & layer_state_t::eOpacityChanged)) {
18894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            // TODO: should we just use an eFlagsChanged for this?
1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1909e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1910e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1911e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
19124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
19130ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
19140ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
19154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
19164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
19196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1920921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
19216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
19224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
19236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
19248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
19254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
19264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
19274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
19284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
19293165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
19303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
19314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
19324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
19334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
19353165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
19364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
19374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
19384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
19394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
19404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
19414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (result == NO_ERROR) {
19466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        addClientLayer(client, *handle, *gbp, layer);
194796f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
19534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
19544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
195792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
1960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
1963a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1964a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGB_565;
1965a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else
19668f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
1967a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1971a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888
1972a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian    if (format == PIXEL_FORMAT_RGBX_8888)
1973a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian        format = PIXEL_FORMAT_RGBA_8888;
1974a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif
1975a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian
19764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
19774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
19784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
19794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
19804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *gbp = (*outLayer)->getBufferQueue();
1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
19834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
19844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
19884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
19894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
19924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
19934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *gbp = (*outLayer)->getBufferQueue();
19944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
1995118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
1996118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
1997ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
19989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
19996710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
20006710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
20016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
20026710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
20036710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
20046710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
20056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
20069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
20079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
20089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
20099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
201013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20126710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
20136710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2014ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
201513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2016ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
20176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2018e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2019ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2020ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2021ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2024b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2025b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
202613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
202701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
202813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
202913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
203013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
203101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
203201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2033692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
203401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
203513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
20364c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
20374c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
203813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
203913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
2040cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    onScreenAcquired(getDefaultDisplayDevice());
20416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
20426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
20436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
20446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
204513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
204613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
204713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
204813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
204913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
205013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
205113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
205213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
205313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
205413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
205513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
205613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
205713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
205813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
205913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
206013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
206113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
2062cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
2063c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
2064c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (hw->isScreenAcquired()) {
2065c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // this is expected, e.g. when power manager wakes up during boot
2066c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        ALOGD(" screen was previously acquired");
2067c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2068c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2069c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
20704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->acquireScreen();
2071c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    int32_t type = hw->getDisplayType();
20729e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
2073c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // built-in display, tell the HWC
2074c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        getHwComposer().acquire(type);
2075c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2076c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2077c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2078c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2079faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
2080948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2081c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2082cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    }
208320128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    mVisibleRegionsDirty = true;
208420128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian    repaintEverything();
2085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2087cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
2088c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
2089c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    if (!hw->isScreenAcquired()) {
2090c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        ALOGD(" screen was previously released");
2091c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2092c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2093c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2094c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    hw->releaseScreen();
2095c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    int32_t type = hw->getDisplayType();
20969e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
2097c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2098948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2099948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2101cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2102cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2103c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2104c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        // built-in display, tell the HWC
2105c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        getHwComposer().release(type);
2106b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2107c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    mVisibleRegionsDirty = true;
2108c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    // from this point on, SF will stop drawing on this display
2109b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2110b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2111c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::unblank(const sp<IBinder>& display) {
2112b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenAcquired : public MessageBase {
2113db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2114db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
2115b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
2116db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        MessageScreenAcquired(SurfaceFlinger& flinger,
2117db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
2118b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
2119db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2120db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
2121db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGE("Attempt to unblank null display %p", mDisplay.get());
21229e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
2123db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGW("Attempt to unblank virtual display");
2124db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
2125db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                mFlinger.onScreenAcquired(hw);
2126db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2127b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2128b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2129b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
2130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    sp<MessageBase> msg = new MessageScreenAcquired(*this, display);
2131db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2134c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::blank(const sp<IBinder>& display) {
2135b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    class MessageScreenReleased : public MessageBase {
2136db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2137db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
2138b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
2139db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        MessageScreenReleased(SurfaceFlinger& flinger,
2140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
2141b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
2142db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2143db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
2144db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGE("Attempt to blank null display %p", mDisplay.get());
21459e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
2146db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                ALOGW("Attempt to blank virtual display");
2147db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
2148db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                mFlinger.onScreenReleased(hw);
2149db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2150b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2151b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2152b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
2153db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    sp<MessageBase> msg = new MessageScreenReleased(*this, display);
2154db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2155b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2156b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2157b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2158b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
216299b49840d309727678b77403d6cc9f920111623fMathias Agopian
2163bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2164bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2165bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2166bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2167bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
216874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2169bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
21719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
21729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
21739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
21749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
21759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
21769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
21779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
21789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
21799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
218074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            result.append(
21819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
21829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
21839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
21849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
218582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
218682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
218725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
218825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
218925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
219025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
219125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
219274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
219335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
219425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
219525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
219625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
219725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
219882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
219974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
220035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
220182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
220225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
220325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
220425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
220525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
220674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
220735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
220825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
22101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
221182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
221274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
221382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
221448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
221582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
221682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
221748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
221882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
221982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
222082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
222182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
222248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
222325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
222474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
222525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
222625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
222725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
222825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
222913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
223074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
223125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
223225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
223325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
223482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
223574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
223682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
223782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
223882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
223982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
224082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
224182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
224248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
22434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
22444b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
22454b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    result.appendFormat("%lld\n", period);
22464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
22474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
22484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.dump(result);
22494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
22504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
22514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
22524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
225313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
22544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
225574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                layer->dumpStats(result);
22564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
225782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
225882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
225982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2260ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
226125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
226274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result)
226325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
226425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
226525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
226625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
226725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
226825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
226925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
227025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
227125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
227225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
227313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
227425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
227525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            layer->clearStats();
227625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
227725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
22784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
22794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimFrameTracker.clear();
228025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
228125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
22826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
22836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
22846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
22856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
22866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
22876547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
22886547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
22896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
22906547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
22916547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
22926547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
22936547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
22946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
22954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
22964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
22974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
22984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
22994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NO_RGBX_8888
23004803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NO_RGBX_8888"
23014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
23034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
23044803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
23064803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
23074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
23094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
23104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
23124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
23134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
23144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
231574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
231674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
231782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
23183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
23193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
23203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
23213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
23223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
23233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
23243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
23253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
23263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
232782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
232882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
232982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
233082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
233182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
233282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2333bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
233482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
23354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
23364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
23373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
23383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
23394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
23403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
23414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
23424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
23434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
23444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
23454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
23463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2347ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
23483e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2349ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2350ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2351ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
23524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
235482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
235582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
235682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
23573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
235874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("Visible layers (count = %d)\n", count);
23593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
236082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
236113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
23623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
236382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2364bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
236582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
23665f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
23675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
23685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
23693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
237074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("Displays (%d entries)\n", mDisplays.size());
23713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
23725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
23735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
237474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
23755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
23765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
23775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
237882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
237982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
23801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
23813e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
238274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
23833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
23841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2385888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
23864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2387ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
23883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
23893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
23903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
23913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
23923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2393ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2394ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2395875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
23969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
23974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
239874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  orientation=%d, canDraw=%d\n",
23994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->getOrientation(), hw->canDraw());
240074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
240182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
240282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2403c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
240482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
240582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2406ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2407ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2408ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
240982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
241082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2411c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2412b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2413b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2414ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2415ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
241774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
241882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
241982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
242074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
242182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
242282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
242482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
242674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
242982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
24313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
243274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
24333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
243474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
243582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
24369c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
24379c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
243874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
243982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
244182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
244282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
244382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
244482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
244713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
244848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2449db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
245048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
245148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
245248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
245348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
245448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
245548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
245648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
245748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
245848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
245948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
246048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
246148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
246248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2463cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2464cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
246563f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
246663f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
246763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
246863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
246963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
247063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
247163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
247263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
247363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
247463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start");
247563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
247663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
247763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
247863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
247963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
248063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
248163f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
248263f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2488041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2489698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
24918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case BLANK:
24928e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross        case UNBLANK:
2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2497a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
249899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
249999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2500e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2501375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2502375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
251299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
251399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2514e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2524b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
252599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2526375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2527375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2528375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2529e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2530375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
253501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
253635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
254153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
254253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
254553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2546cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2547cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2548cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
25554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
25564d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
25574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
25584d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
255953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
256053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
256153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
256253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
256353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
256453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2565a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2566a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2567a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2568a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2569a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2570a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
257201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2575b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
257612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
25804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
25814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2582ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2583ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2584ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2585ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2586ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2587ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2588ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2589ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2590ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2591ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2592ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2593ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2594ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2595ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2596ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2597ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2598ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2599ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
26009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
26019c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
26029c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
26039c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
26049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
26059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
26069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
26079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
26089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
26099c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2610794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2611794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2612794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2613794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
26149c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
26159c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
26169c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
26179c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
26189c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
26199c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
26209c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
262753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
262887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
262999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
263053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
263153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
263259119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
26332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
26342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
263559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
26362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
26372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
26382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
26392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * to the calling binder thread, where they are executed. This allows
26402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * the calling thread to be reused (on the other side) and not
26412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * depend on having "enough" binder threads to handle the requests.
26422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
26432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
26442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
26452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
26462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
26472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
26482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
26492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
26502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
26512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    mutable Barrier barrier;
26522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    volatile int32_t memoryBarrier;
26532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
26542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
26552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
26562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
26572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
26582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
26592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
26602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
26612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
26622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
26632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * this is called by our "fake" BpGraphicBufferProducer. We package the
26642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * data and reply Parcel and forward them to the calling thread.
26652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
26662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
26672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            const Parcel& data, Parcel* reply, uint32_t flags) {
26682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
26692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
26702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
26712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        android_atomic_acquire_store(0, &memoryBarrier);
26722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
26732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            // if we've exited, we run the message synchronously right here
26742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
26752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
26762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
26772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
26782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
26792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
26802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return NO_ERROR;
26812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
26822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
26832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
26842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * here we run on the binder calling thread. All we've got to do is
26852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
26862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
26872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
26882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        android_atomic_release_load(&memoryBarrier);
26892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (message.what == MSG_API_CALL) {
26902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            impl->asBinder()->transact(code, data[0], reply);
26912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
26922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else if (message.what == MSG_EXIT) {
26932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
26942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
26952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
26962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
26972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
26982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) :
26992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        impl(impl), looper(new Looper(true)), result(NO_ERROR),
27002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending(false), exitRequested(false) {
27012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
27042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
27052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
27062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
27072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
27082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
2711aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
27122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
27132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
27142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
27162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
27192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
27202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight,
27213ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ) {
27222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
27232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
27242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
27252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
27262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
27272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
27282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
27295ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
27305ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
27315ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
27325ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    if (!producer->asBinder()->localBinder()) {
27335ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
27345ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
27355ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
27365ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
27375ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
27385ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
27395ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
27405ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
27412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
27422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
27432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
27442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
27452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
27462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
27472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
27482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
27492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
27502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
27512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
27522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                uint32_t reqWidth, uint32_t reqHeight,
27533ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                uint32_t minLayerZ, uint32_t maxLayerZ)
27542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
27552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              reqWidth(reqWidth), reqHeight(reqHeight),
27562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
27572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
27582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
27592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
27602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
27612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
27622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
27632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
27642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
27652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
27660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = flinger->captureScreenImplLocked(hw,
27673ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                    producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
27682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
27692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
27702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
27712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
27722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
27739eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
27749eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
27759eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
27769eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
27779eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
27789eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
27799eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
27802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
27812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
27822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
27832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
27842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
27862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
27872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
27882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
27893ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian            reqWidth, reqHeight, minLayerZ, maxLayerZ);
27902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
27922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
27932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
27942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
27952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
2796118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2797118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2798180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2799180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
2800180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
2801180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight,
2802180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
2803180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        bool yswap)
2804180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
2805180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
28063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
2807180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2808180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
2809180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
2810180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
2811180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
2812180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2813180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
28143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
2815180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2816180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
28173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.setViewportAndProjection(reqWidth, reqHeight, hw_w, hw_h, yswap);
28183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
2819180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2820180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
28213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
2822180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2823180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
2824180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
2825180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
2826180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
28271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
2828180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
2829180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
2830180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
2831180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
2832180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    layer->draw(hw);
2833180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
2834180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
2835180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
2836180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
2837180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
2838180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2839180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
2840180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
2841931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
2842180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
2843180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2844180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
28452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
28462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
28472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
28482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, uint32_t reqHeight,
28493ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ)
285074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2851fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2852fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
2853180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
2854180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
2855180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
2856180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2857180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
2858180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
2859180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
2860180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
2861180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
2862180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2863180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
2864180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
2865180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
28660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
28670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
286883cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
28690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
287074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
28710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    status_t result = NO_ERROR;
28720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
28733ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
28743ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
28752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
28760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
28770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
28784ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
28790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
28800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
28812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
28820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
28830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
28840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
28850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
28860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
28870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
28880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
28890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
28900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
28910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
28920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
28930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
28943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
28953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
28963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
28973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
28980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
28990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
29000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
29010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
29020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        renderScreenImplLocked(hw, reqWidth, reqHeight,
29030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                                minLayerZ, maxLayerZ, true);
2904d555684cb36dfb959694db76962e570184f98838Mathias Agopian
29052d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // Create a sync point and wait on it, so we know the buffer is
29062d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // ready before we pass it along.  We can't trivially call glFlush(),
29072d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // so we use a wait flag instead.
29082d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // TODO: pass a sync fd to queueBuffer() and let the consumer wait.
29092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
29102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
29112d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
29122d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
29132d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            EGLint eglErr = eglGetError();
29142d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
29152d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            if (result == EGL_TIMEOUT_EXPIRED_KHR) {
29162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                ALOGW("captureScreen: fence wait timed out");
29172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
29182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                ALOGW_IF(eglErr != EGL_SUCCESS,
29192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                        "captureScreen: error waiting on EGL fence: %#x", eglErr);
29202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
29212d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        } else {
29222d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
29232d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            // not fatal
29242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
29252d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden
2926d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
2927d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
2928d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
2929d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
2930d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
2931d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
2932d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
2933d555684cb36dfb959694db76962e570184f98838Mathias Agopian
29340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
29350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
29360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
29370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
29380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
29390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
29400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
29410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
294274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
29430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                window->queueBuffer(window, buffer, -1);
294474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
29450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
29460aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
294774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
29480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
294974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
295074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
295174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
295274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
295374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
2954d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
2955d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
2956fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
2957d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
2958d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
2959d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
2960fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
2961fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
2962fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
2963fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
2964fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
2965fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
2966fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
2967fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
2968fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
2969fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
2970fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
2971fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
2972fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
2973fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
2974fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            ALOGE("%c index=%d, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
2975fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
2976fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
2977fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
2978fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
2979fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
2980fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
2981fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
29821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
29831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2984921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
2985921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2986921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2987921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
298813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
2989921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
2990921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
2991921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
2992921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
2993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2994be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
299513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
299613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
2997be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
29981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
29991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3000be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3001be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3002be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
30031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
30041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3005be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3006be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3007be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3008be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3009921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3010921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3011921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3012921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
30133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
30143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
3015e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3016e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
30173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
301801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0) {
3019da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3020da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3021b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
30227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3023b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
302496f0819f81293076e652792794a961543e6750d7Mathias Agopian
3025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
30263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
30273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
30283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
30293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
30303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
30313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
30323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
30333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
30343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3035