SurfaceFlinger.cpp revision ee44edd0acccbf5eaa918d75737c3b65ee04fff7
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>
2486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
25b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
3867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
45392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
51cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
58ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
640f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
65faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
66d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
67d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
73a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
78875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
89ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
90ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12499b49840d309727678b77403d6cc9f920111623fMathias Agopian
12599b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12699b49840d309727678b77403d6cc9f920111623fMathias Agopian
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
134875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
137a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
1384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
142a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
147ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
148ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
149faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
150948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
1519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mDaltonize(false),
1529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mHasColorMatrix(false)
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
154a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1588afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
159b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
16050210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
161b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1668afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1678afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
17063f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
17163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
173c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
174c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
18099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
18199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
185a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
186a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
189c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
19299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
19413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
197a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2007e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
20396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
20496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
20596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
20696f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
212dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
2313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
2328dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
233dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
268e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2699e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
273692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
286a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2873330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
293921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
298a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
299a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
303921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
306921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
318faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
319faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3205167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3215167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden        const char* label) :
3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mPhaseOffset(phaseOffset),
3240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
3265167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncEventLabel(String8::format("VSYNC-%s", label)),
3270a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mDispSync(dispSync) {}
328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // Do NOT lock the mutex here so as to avoid any mutex ordering issues
333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // with locking it in the onDispSyncEvent callback.
334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3350a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            status_t err = mDispSync->addEventListener(mPhaseOffset,
336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3415167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3495167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        Mutex::Autolock lock(mMutex);
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            Mutex::Autolock lock(mMutex);
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3650a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
3675167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
3680a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
3780a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const nsecs_t mPhaseOffset;
3790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
3805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
3815167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
3820a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex mMutex;
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
388faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
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
422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferProducer> producer;
423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferConsumer> consumer;
424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            BufferQueue::createBufferQueue(&producer, &consumer,
425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    new GraphicBufferAlloc());
426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza
427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
428b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    consumer);
42919e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall            int32_t hwcId = allocateHwcDisplayId(type);
430f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
43119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
432b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    fbs, producer,
43305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                    mRenderEngine->getEGLConfig());
434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
43886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                ALOGD("marking display %zu as acquired/unblanked", i);
4392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
442f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
444cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // make the GLContext current so that we can create textures when creating Layers
446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // (which may happens before we render something)
447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
448a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
449028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4515167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            vsyncPhaseOffsetNs, true, "app");
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mEventThread = new EventThread(vsyncSrc);
4530a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            sfVsyncPhaseOffsetNs, true, "sf");
4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mSFEventThread = new EventThread(sfVsyncSrc);
4560a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mEventQueue.setEventThread(mSFEventThread);
457028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
460d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    // set a fake vsync period if there is no HWComposer
462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mHwc->initCheck() != NO_ERROR) {
463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.setPeriod(16666667);
464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
465faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
46792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
47113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
472a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
473a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4779e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
486a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
496d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
4982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
500097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
503134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    if (configs == NULL) {
5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5107aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5117aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5127aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
513692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5149e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
515692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5201604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5211604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5221604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
523c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5411604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    const Vector<HWComposer::DisplayConfig>& hwConfigs =
5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            getHwComposer().getConfigs(type);
5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    for (size_t c = 0; c < hwConfigs.size(); ++c) {
5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float xdpi = hwConfig.xdpi;
5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float ydpi = hwConfig.ydpi;
5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
5737f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
5747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
5771604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.w = hwConfig.width;
5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.h = hwConfig.height;
5817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
5827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.fps = float(1e9 / hwConfig.refresh);
58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden
58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
59691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
59791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
59891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.presentationDeadline =
59991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden                hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        configs->push_back(info);
6058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
609dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
61089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
61167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
61267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
61367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
61467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
61567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
61667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
61767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
61867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
61967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
62067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
62167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
62267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
62424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
62524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
62624a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
62724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
62824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
630dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
6496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
6546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
6556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
6566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
6576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
6586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
6596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
6606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
6617306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
6627306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
663784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
6649ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
6657306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
6667306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
6707306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
6766c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
6776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
6786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
6796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
6806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
6816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
682888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
683c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
684c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
685d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
686d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
687d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
688d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
689d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
690d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
691d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
692d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
693d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
694d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
695d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
696d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
697d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
698d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
699d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
7008aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
701bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
702bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
72099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
722c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
72699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
727c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
72899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
72999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
73099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
73199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
73299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
73399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7354f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
7364f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
7374f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
7384f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
73999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
741faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
742faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
743948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
744faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
745d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
746d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
747faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
74843601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
749faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
750faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
752faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
753faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
754948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
755948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
756948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
757948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
758948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
759948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
760948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
762faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
763faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
764faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
766faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
767faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
768faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
769d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
770d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
771faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
772faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
773faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
774faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
775948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
776faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
777faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
778d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
779d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
780faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
781faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
782faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
783948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
784948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
785948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
786faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
787faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
788faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
789d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
790faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
791d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
792d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
793d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
794d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
795faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
796148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
797d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
798d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
799d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
800d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
801d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
802d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
803148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
804148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
805148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
806148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
807148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
808148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
809148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
810148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
811148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
812148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
8139e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8149e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
8159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
816692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
817692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
8189e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
819692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
820692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
8219e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
8229e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
8239e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8249e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
8253ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
8268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8278630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
82881cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
829faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
83081cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
8318630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8328630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
8341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
83599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
8366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::TRANSACTION: {
8376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageTransaction();
8386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
8396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
8406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
8416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
8426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
8435878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
8446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
8455878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
8465878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
8475878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
8486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
8496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
8506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
8516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
8526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
8536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
8546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
8556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8596b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
8614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
86287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
8636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8686b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
8706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
8714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8723a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
8734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
887cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
8922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
897cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
899cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
900cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
9013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
9023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
9033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
905da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
907cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
908cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
909cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
910cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
911cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
915bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
916bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
917bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
918bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
919bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
920bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
922cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
923cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
925cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
9261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
928cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
930cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
931cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
932cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
933cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
934cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
935cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
936cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
937a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
938cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
939cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
9401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
942cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
944cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
9454b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
946faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
947faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
948faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
949faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
950faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
951faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
952faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
953948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
954faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
955faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
956faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9575167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
958faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
9592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
960faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
961faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
962faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
963faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
9654b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
9664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
967a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
9684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
9694b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
9704b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
9714b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
9724b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
9734b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
9744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
9754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
9764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
977cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
978cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
979cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
98152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
982cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
98387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
98487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
985ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
9861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
98792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
988ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
989ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
9914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
9927e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
9937e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
9942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            if (hw->isDisplayOn()) {
9951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
996ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
9977e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
9981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
999ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
10001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
10011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
1002ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
1003a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1004a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1005a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1006a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1007ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
1008ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
100987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
101087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
10113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
10124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
10137e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
10147e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
10157e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
10163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
10173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1018cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
10193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1020cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
1021028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1022b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1023b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1024b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1025b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1026b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1027b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1028b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1029b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1030b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1031b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1032b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1033b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1034b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1035b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1036b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1037b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1038b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1039b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1040b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1041b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1042b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
10437143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1044b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1045b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1046b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1047b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1048028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1049028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
105052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
105152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
105252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
1053a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
1054a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
1055a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1056a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
1057a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
1058a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
105913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
1060a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
1061a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
1062a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
1063a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
1064a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
1065a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
106613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
1067a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
10689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
1069a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
1070a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
1071a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1072a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1073a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
1074a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
1075a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
1076a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1077a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
107892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
1080e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
1081e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
108213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
1083cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
1084e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
1085a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
1086a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
1087a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1088a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
1089a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
1090a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
1091a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
1093a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
10941e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
109552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
109687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
1097a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
109803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        // If possible, attempt to use the cursor overlay on each display.
109903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
110003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            sp<const DisplayDevice> hw(mDisplays[dpy]);
110103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const int32_t id = hw->getHwcDisplayId();
110203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (id >= 0) {
110303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const Vector< sp<Layer> >& currentLayers(
110403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    hw->getVisibleLayersSortedByZ());
110503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const size_t count = currentLayers.size();
110603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                HWComposer::LayerListIterator cur = hwc.begin(id);
110703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const HWComposer::LayerListIterator end = hwc.end(id);
110803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
110903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    const sp<Layer>& layer(currentLayers[i]);
111003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    if (layer->isPotentialCursor()) {
111103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        cur->setIsCursorLayerHint();
111203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        break;
111303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
111403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
111503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
111603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
111703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
111852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
111952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
112038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
112138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
112238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
112338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
112438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
112552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
1126cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
112752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1128cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1129cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
113052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
113192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1134cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1135cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
113602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
113702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
113802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
113902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1140cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1142cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
114387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
114452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
11454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
11464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
114752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1152841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1153b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1154a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1155a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1156c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
115752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1158ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
11592a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
11602a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
11612a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
11622a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
1163875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11642a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1165e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
116652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
11686da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
11696da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
11706da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
11716da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
11726da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11736da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
117492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
1177da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
117852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1179e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1180e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
11811e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
11821e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
118352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1184d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
118552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
118752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1188d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
118952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1190ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1191e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1192e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1193a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1194a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
11956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
11966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
11976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
11986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
11996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
120287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1204841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1205841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
12067cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
12077cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
12087cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
12097cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
12107cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
12117cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1212ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1213ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1214ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1215ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1216ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1217ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1218ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1219ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1220ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1221ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
122387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1224ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1225ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1226ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1227ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1228ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
12293d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
123187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
12323d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
12333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
124313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
12543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
125892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
125992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
126092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1262e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
126392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
126592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
126693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
126792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
126892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
126992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
127292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
127592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
12763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
127727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
127827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
127927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
128002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1281875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
128202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
128302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
128402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
12859e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
12867adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
128702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
128892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
128992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
129092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
129192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
129292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
12943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1295097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1296097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
12971474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
129993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
130093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
130193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
130202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
130302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
130402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
130593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
130693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
130793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
130893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
130993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
131092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
131193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1312db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
131393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
131493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
131593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
131693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
131700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
131800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
131900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
132000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
132100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
13224fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
132393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
132447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
132547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
132647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
132792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
132892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
132992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
133192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
133292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
133392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1335e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1336cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
133799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1338db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1339b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1340b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1341b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1342b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                            new GraphicBufferAlloc());
1343db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
134402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
134599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
134602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
134702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
134802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
134999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1350db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
13511f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int width = 0;
13521f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int status = state.surface->query(
13531f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_WIDTH, &width);
13541f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
13551f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query width (%d)", status);
13561f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int height = 0;
13571f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            status = state.surface->query(
13581f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_HEIGHT, &height);
13591f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
13601f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query height (%d)", status);
13611f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
13621f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
13631f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
13641f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                hwcDisplayId = allocateHwcDisplayId(state.type);
13651f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            }
13661f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza
1367db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1368b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    *mHwc, hwcDisplayId, state.surface,
1369b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    bqProducer, bqConsumer, state.displayName);
1370db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1371db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
137247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
137399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
137499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1375cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1376cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1377cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1378cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
137902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1380cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1381cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1382b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        dispSurface = new FramebufferSurface(*mHwc, state.type,
1383b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                bqConsumer);
1384b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        producer = bqProducer;
1385cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1386cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1387cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
138899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1389cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
139019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
139119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
139205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
139305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1394cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1395cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
13964fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
13978dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1398cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
13991c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
14001c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
14011c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
14021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
14031c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
14041c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
14051c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
14067adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
14071c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
140893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
140992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
141092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
14158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
14168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
14178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
14188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
14208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
14218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
14238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
14248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
14258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
14278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
14288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
14308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
14318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
14328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
14338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
14358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
14368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
14378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
14388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
14398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
14411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
14428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
14438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
14448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
14458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
14468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
14478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
14488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
14508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
14518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
14528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
14538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
145491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
14558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
14568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
14578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
14588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
14598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
146091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
146191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
146291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
146391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
146491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
146591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
146691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
146791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
14688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
146991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
14708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
14718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
14728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
14753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
14763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
14791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
14803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
14813559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
14833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
14843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
14853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
14863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
14873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
14883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
14903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
14911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
14923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
14933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
14943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
14953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
14963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
14971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
14981501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
14991501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
15001501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
15010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
150603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
150703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
150803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
150903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
151003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
151103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
151203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    HWComposer& hwc(getHwComposer());
151303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
151403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        sp<const DisplayDevice> hw(mDisplays[dpy]);
151503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const int32_t id = hw->getHwcDisplayId();
151603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        if (id < 0) {
151703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
151803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
151903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const Vector< sp<Layer> >& currentLayers(
152003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hw->getVisibleLayersSortedByZ());
152103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const size_t count = currentLayers.size();
152203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        HWComposer::LayerListIterator cur = hwc.begin(id);
152303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const HWComposer::LayerListIterator end = hwc.end(id);
152403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
152503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
152603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                continue;
152703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
152803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const sp<Layer>& layer(currentLayers[i]);
152903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            Rect cursorPos = layer->getPosition(hw);
153003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hwc.setCursorPositionAsync(id, cursorPos);
153103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            break;
153203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
153303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
15344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
15354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
15364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
15374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
15384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
15394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
15404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
15414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
15424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
15434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
15444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
15454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
15464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
15474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
15484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
15494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
15512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
15522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
15534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
155787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
155887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1560841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1561841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
157013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
15731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
157501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
157687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
157787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
157887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1579ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1580ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1581ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1583ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1586ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1598a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1599a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1600a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1601a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1602a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1603a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1604a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1605a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1606a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1607a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1610da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
16114125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
16125219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
16174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
16184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
16194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
16204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
16212ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
16224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
16234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
16244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1625a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
16264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
16274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
16282ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
16294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
16334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
16564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1659a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1670a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
16724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
16734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
168087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
16848b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1685a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1688a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1689a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
169287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
169587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
169687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
169792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
16994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
17004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
170192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
170292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
170387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
170487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
17056b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
170899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
17094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
17101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
17116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
171251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
171351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
171451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
171551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
171651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
171751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
171851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
171951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
172051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
172151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
172251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    Vector<Layer*> layersWithQueuedFrames;
172351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
17241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
17256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
17266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
17276b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
17286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                layersWithQueuedFrames.push_back(layer.get());
1729ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
1730ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
17316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
1732ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
1733ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
17346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
173551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
173651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
173751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        Layer* layer = layersWithQueuedFrames[i];
173887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
1739ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
17401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
174187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
17424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
17434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
17443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
17456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
17466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
17476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
17486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
17496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    if (frameQueued && layersWithQueuedFrames.empty()) {
17506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
17516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
17526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
17536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
17546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return !layersWithQueuedFrames.empty();
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1757ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1758ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1759ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1760ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1761ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
176299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
176487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17667143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
17677143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
17687143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
17697143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
17707143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
17717143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
17727143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
17737143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
17747143316af216fa92c31a60d4407b707637382da1Dan Stoza
177587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
177687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1777b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
17784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
17810f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
178229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
178329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
178429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
17854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
17870f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
178829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1789df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
179095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
17910f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
17924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
179429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
17954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
17964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
18013f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine        if (!doComposeSurfaces(hw, dirtyRegion)) return;
1802ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1803ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
18049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
18059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
18069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
18079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
18089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        engine.beginGroup(colorMatrix);
1809ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1810ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        engine.endGroup();
1811ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
18144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1815da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1816da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1817da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18203f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
182385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
18248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
18251e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
18261e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1827a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1828d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
182985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1830875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1831c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1832c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
18333f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
18343f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
18353f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
18363f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
18373f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
1838c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1839a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1840a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
184185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1842e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1843b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1844b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1845b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
18463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1847b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
18483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1849b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1850766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1851766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1852766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1853766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1854766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1855766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1856766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1857766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1858766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1859766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1860766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1861766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1862766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1863766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1864b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
186587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1866b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
186755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1868b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1869a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1870f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1871766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1872766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1873f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1874f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1875f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1876766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1877f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1878f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1879f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1880f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
18813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1882f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
18833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
18843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
18853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1886f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1887f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
188885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
18894b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
189085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
189185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
189285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
18934b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
189413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
189685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
189785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
189885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
189985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
190013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
19014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
190285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
190385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
190403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    case HWC_CURSOR_OVERLAY:
190585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1906ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
190785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
190885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
19094125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
191085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1911cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
191585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
191685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
191785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1918cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
191985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1920a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1921da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1922da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1923da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
192486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
1925da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1926da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1927cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1928a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
192985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
193085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
193185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
193285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
193385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
193413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
193585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
193685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
193785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
193885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
193985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
19404b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
19414b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1942f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1943f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
19443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
19453f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
194955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
19503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
19513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1954ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client,
1955ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
19566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
195713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
19581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
195996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
1960ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
19614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
196296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1963921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1964921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
1965097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
196696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
196796f0819f81293076e652792794a961543e6750d7Mathias Agopian
19683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
196996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
197013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
19726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
1973076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
19746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1980c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
1981dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1982dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1983dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
19843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
1989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
199199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19968b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
19978b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
19988b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
19998b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
20008b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
20017c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2002698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
200328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2004e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
20052d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
20062d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
20072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
20082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
20097c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
20102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
20112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
20127c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
20137c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
20147c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
20152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
20162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
20172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
20182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
20192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
20202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2021e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2022e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2023e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2024e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2025b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2026b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2027e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2028698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2029698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2030d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2031d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2032d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2033d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2034d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2035d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2036d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2037d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2038097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2039d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2040d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2041d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2042d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2043d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2044d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2045d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2046d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2047698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2048386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
204928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2050386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
205128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2052698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2053386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2054386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2055386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
20562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
20572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
20582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
20592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2060386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
20612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2062386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2063386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2064386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2065386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
20662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
20672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2068386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2069386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2070cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2074e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2075e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
20769a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
20779a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
20789a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
20799a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2080e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
20819a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
20823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2084e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2085097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2086e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2087e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2088e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2089e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2090e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2091e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2092e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2095e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
209600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2099e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2104e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2105e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2107e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2108e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
211047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
211147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
211247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
211347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
211447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
211547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
211647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
211747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
211847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
211947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2120e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2121e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2122e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2123e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2124e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2125e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2126e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2127e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
212913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2132e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
2133e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
2134e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2135e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2136e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2137e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2138e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2139e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
2140e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2141e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2142e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2143e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2144e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2145e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2146e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2147e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2148e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2149e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2150e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2151e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2152e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
2153e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
2154e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2155e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2156e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2157e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2158e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2160e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2161e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
21644125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if ((what & layer_state_t::eVisibilityChanged) ||
21654125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                (what & layer_state_t::eOpacityChanged)) {
21664125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            // TODO: should we just use an eFlagsChanged for this?
2167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
2171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
2172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
2178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
21894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
21900ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
21910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
21924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
21934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
21966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2197921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
21986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
21994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
22006e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
22018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
22024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
22034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
22054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22063165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
22073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
22084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
22094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
22104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
22123165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
22134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
22144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
22154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
22164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
22174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
22184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (result == NO_ERROR) {
22236710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        addClientLayer(client, *handle, *gbp, layer);
222496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
22264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
22304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
22314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
223492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
22408f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
22454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
22464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
22474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2248b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
22504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
22524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
22564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
22574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
22604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2261b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
22624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2263118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2264118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2265ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
22669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
22676710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
22686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
22696710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
22706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
22716710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
22726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
22736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
22749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
22759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
22769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
22779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
227813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22806710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
22816710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2282ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
228313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2284ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
22856710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2286e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2287ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2288ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2289ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2292b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2293b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
229413a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
229501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
229613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
229713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
229813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
229901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
230001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2301692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
230201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
230313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
23044c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
23054c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
230647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
230747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
230813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
230913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
23102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
23116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
23126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
23136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
23146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
231513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
231613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
231713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
231813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
231913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
232013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
232113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
232213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
232313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
232413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
232513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
232613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
232713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
232813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
232913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
233013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
23312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
23322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
23332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
23342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
23352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
23362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
233713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
23382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
23392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2340c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2341c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2342c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
23442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
23452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
23462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
23472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2348c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
23502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2351c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2352c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2353c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2354948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2355c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
23582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
23592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2360c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2361948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2362948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2363cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2364cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2365cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2366c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
23682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
23692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
23702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
23712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2372b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
23762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2377db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2378db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
23792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2380b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
23812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
23822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
23832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2384b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
23852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2386db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
23872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
23887306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
23899e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
23902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
23912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2392db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
23932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2394db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2395b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2396b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2397b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
23982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2399db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2400b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2401b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2402b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2403b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
240799b49840d309727678b77403d6cc9f920111623fMathias Agopian
2408bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2409bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2410bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2411bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2412bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
241374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2414bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2416fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
24179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
24189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2419fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2420fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
24219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2422fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2423fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2424fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
24259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
24269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
242925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
243025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
243125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
243225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
243325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
243474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
243535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
243625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
243725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
243825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
243925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
244174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
244235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
244382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
244425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
244525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
244625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
244725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
244874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
244935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
245025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2451c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2452c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2453c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2454c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2455c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2456c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2457c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
24591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
246082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
246174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
246282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
246348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
246482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
246582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
246648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
246782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
246882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
246982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
247082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
247148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2472c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2473c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
247425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
247525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
247625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
247725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
247813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
247974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
248025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
248125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
248225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
248382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
248474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
248582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
248682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
248782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
248882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
248982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
249082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
249148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
24924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
24934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
249486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
24954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
24964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2497d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
24984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
24994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
25004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
25014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
250213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
25034b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2504d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
25054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
250682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
250782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
250882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2509ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
251025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2511c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
251225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
251325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
251425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
251525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
251625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
251725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
251825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
251925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
252025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
252125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
252213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
252325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2524d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
252525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
252625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
25274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2528d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
252925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
253025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
25316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
25326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
25336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
25346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
25356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
25366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
25376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
25386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
25396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
25406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
25416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
25426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
25436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
25444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
25454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
25464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
25474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
25484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
25494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
25504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
25524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
25534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
25554803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
25564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
25584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
25594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
25604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
256174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
256274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
256382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
25643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
25653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
25663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
25673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
25683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
25693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
25703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
25713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
25723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
257382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
257582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
257682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
257782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2579bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
25814803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
25824803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
25833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
25843e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
25854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
25863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25874803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
25884803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
25894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
25904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
25914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
25923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2593ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
25943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2595ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2596ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2597ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
259841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
259941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
260041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
260124cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
260224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
260341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
260441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
260541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
260641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
26074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
260882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
260982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
261082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
261182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
26123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
261386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
26143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
261582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
261613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
26173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
261882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2619bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
262082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
26215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
26225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
26235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
26243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
262586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
26263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
26285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
262974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
26305f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
26315f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
26325f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
263382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
263482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
26351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
26363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
263774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
26383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2640888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
26414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2642ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
26433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
26443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
26453e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
26463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2648ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2649ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2650875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
26519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
26524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
26532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
265574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
265682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
265782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2658c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
265982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
266082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2661ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2662ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2663ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
266482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
266582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2666c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2667b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2668b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2669ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2670ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
267182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
267274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
267382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
267482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
267574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
267682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
267782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
267882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
267982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
268082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
268174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
268282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
268382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
268482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
268582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
26863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
268774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
26883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
268974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
269082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
26919c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
26929c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
269374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
269482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
269582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
269682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
269782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
269882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
269982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
270213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
270348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2704db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
270548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
270648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
270748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
270848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
270948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
271048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
271148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
271248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
271348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
271448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
271548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
271648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
271748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2718cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2719cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
272063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
272163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
272263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
272363f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
272463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
272563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
272663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
272763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
272863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
272924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
273063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
273163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
273263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
273363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
273463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
273563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
273663f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
273763f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2743041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2744698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
2746d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
2747d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
27482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
2749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2753a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
275499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
275599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2756e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2757375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2758375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
27601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
27611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
27631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
27651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
27661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
27671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
276899b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
276999b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2770e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
27711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
27721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
27731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
27741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
27771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2780b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
278199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2782375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2783375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2784375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2785e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2786375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
279101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
279235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
279753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
279853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
280153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2802cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2803cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2804cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2805e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2809cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
28114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
28124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
28134d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
28144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
281553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
281653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
281753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
281853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
281953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
282053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2821a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2822a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2823a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2824a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2825a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2826a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
282801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2831b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
283212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
28364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
28374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2838ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2839ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2840ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2841ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2842ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2843ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2844ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2845ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2846ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2847ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2848ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2849ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2850ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2851ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2852ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2853ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2854ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2855ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
28569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
28579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
28589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
28599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
28609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
28619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
28629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
28639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
28649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
28659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2866794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2867794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2868794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2869794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
28709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
28719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
28729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
28739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
28749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
28759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
28769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2878f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
2879f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
2880f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
2881645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
2882645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
2883f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
2884f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
2885ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
2886ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
2887ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
2888ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
2889ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
2890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
289553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
289687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
289799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
289853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
289953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
290059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
29012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
29022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
290359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
29042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
29052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
29062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
2907b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
2908b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
2909b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
2910b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
29112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
29122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
2913b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
2914b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
2915b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
2916b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2917b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
2918b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
2919b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
2920b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
2921b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2922b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
2923b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
2924b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
2925b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
2926b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
29272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
29282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
29292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
29302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
29312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
2932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
29332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
29342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
29352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
29362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
29382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
29392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
29402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
29412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2943b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
2944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
2945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
29462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
29472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
2948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
29492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
29502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
29512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
29522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
2953b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
2954b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
2955b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
2956b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
29572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
29582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
29592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
2960b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
2961b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
2962b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
29632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
29642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
29652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
2966c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
29672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2970b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
29712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
29722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
29732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
2974b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
2975b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
2976b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
2977b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
2978097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
29792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
2980b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
29812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
29822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
29832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
2986b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
2987b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
2988b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
2989b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
2990b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitRequested(false)
2991b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
2992b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
2993b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
29942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
29952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
29962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
29972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
29982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
29992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
30002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3001b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
30022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3003aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
30042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3005b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3006b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3007b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
30082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
30092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
30102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
30112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
30142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3015c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3016c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3017c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
30182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
30192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
30202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
30212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
30222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
30232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
30242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
30255ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
30265ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
30275ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3028097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    if (!IInterface::asBinder(producer)->localBinder()) {
30295ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
30305ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
30315ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
30325ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
30335ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
30345ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
30355ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
30365ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3037c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3038c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3039c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3040c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3041c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3042c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3043c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3044c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3045c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3046c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3047c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3048c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3049c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3050c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3051c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3052c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3053c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3054c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3055c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3056c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3057c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
30582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
30592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
30602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
30612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3062c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
30632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
30642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3065c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3066c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
30672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
30682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
30692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
30702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
30712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3072c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3073c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3074c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                bool useIdentityTransform, Transform::orientation_flags rotation)
30752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3076c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
30772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3078c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3079c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews              rotation(rotation),
30802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
30812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
30822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
30842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
30852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
30872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
30882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3089c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3090c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3091c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                    useIdentityTransform, rotation);
3092097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
30932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
30942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
30962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
30979eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
30989eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
30999eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
31009eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
31019eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
31029eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
31039eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
31042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
31052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
31062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
31072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
31082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
31092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
31102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
31112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
31122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3113c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3114c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            useIdentityTransform, rotationFlags);
31152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
31162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
31172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
31182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
31192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
31202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3122118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3123180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3124180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3125180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3126c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3127180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3128c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3129180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3130180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
31313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3132180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3133180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
313489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
313589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
313689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
31370e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3138180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3139c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3140c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3141c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3142c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3143c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3144c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3145c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3146c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3147c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3148c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3149c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3150be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3151be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3152c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3153c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3154c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3155c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3156be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3157be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3158c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3159c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3160180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
31613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3162180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3163180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3164c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3165c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
31663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3167180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3168180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
31693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3170180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3171180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3172180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3173180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3174180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
31751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3176180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3177180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3178180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3179180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3180c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3181180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3182180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3183180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3184180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3185180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3186180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3187180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
3188180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
3189931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3190180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3191180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3192180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
31932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
31942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
31952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3196c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3197c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3198c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, Transform::orientation_flags rotation)
319974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3200fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3201fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3202180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
3203180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
3204180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
3205180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3206180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3207180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3208180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3209180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3210180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3211180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3212180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3213180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3214180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
32150aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
32160aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
321783cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
32180aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
321974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
32200aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    status_t result = NO_ERROR;
32210aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
32223ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
32233ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
32242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
32250aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
32260aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
32274ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
32280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
32290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
32302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
32310aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
32320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
32330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
32340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
32350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
32360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
32370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3238866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
32390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
32400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
32410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
32420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
32430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
32443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
32453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
32463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
32473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
32480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
32490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
32500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
32510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3252c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3253c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3254c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3255d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3256866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3257866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3258866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3259866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3260866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3261866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
32629707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
32639707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3264866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3265866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3266866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
32672d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3268866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3269866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3270866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3271866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3272866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3273866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
32742d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3275866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3276866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3277866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3278866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3279866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3280866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3281866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3282866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3283866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3284866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3285866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3286866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3287866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3288866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
32892d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3290866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
32912d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
32922d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3293d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3294d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3295d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3296d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3297d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3298d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3299d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3300d555684cb36dfb959694db76962e570184f98838Mathias Agopian
33010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
33020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
33030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
33040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
33050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
33060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
33070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
33080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
330974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3310afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall                // queueBuffer takes ownership of syncFd
3311866399093f9f60e7305f291e688abb456bace710Riley Andrews                window->queueBuffer(window, buffer, syncFd);
331274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
33130aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
33140aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
331574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
33160aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
331774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
331874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
331974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
332074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
332174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3322d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3323d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3324fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3325d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3326d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3327d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3328fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3329fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3330fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3331fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3332fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3333fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3334fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3335fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3336fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3337fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3338fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3339fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3340fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3341fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
334286efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
3343fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3344fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3345fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3346fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3347fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3348fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3349fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
33501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
33511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3352921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3353921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3354921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3355921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
335613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3357921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3358921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3359921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3360921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3362be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
336313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
336413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3365be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
33661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
33671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3368be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3369be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3370be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
33711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
33721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3373be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3374be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3375be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3376be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3377921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3378921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3379921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3380921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
33813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
338247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) {
3383e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
33853ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
338647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) {
3387da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3388da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
33907303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
339296f0819f81293076e652792794a961543e6750d7Mathias Agopian
3393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
33943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
33953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
33963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
33973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
33983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
33993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
34003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
34013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
34023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3403