SurfaceFlinger.cpp revision 4e63777f75e9756c74352e62e79dfa8a994de2b3
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
179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza// #define LOG_NDEBUG 0
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
191c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
21921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2463f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
2586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
26b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3699b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
38c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
3967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
40c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
45e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
46392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
51d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
52cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
560a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h>
571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
60ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
660f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
67faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
68d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
69d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
74a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
75a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
81ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
82875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
91ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
92ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12699b49840d309727678b77403d6cc9f920111623fMathias Agopian
12799b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12899b49840d309727678b77403d6cc9f920111623fMathias Agopian
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1304f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
136875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1414b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1438afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
145a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
150ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
151ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
1524a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
153faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
154948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mLastSwapTime(0)
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
161a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
166b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
16750210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
168b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1738afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
17663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
17763f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
17863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1798afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
180c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
181c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
182c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
183c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
184c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
185c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
18999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
19199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
19299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
195a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
196a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
197a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
200c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
20513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
20699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
208a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
20999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
21099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2117e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
21496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
21596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
21696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
21796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
222dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
223dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
24253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2438dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
268692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
2699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
270692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
273692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
27453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
275692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
276692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
277692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2799e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
283692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2869a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2879a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2889a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2899a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
296a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2973330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
303921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
307a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
308a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
309a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3100a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3110a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3120a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3130a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
320921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
323921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
324921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
326921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
327921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
328921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
330921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3345167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3354a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3364a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3370a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3380a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3394a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3404a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
341db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
342db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
343db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
344db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
345db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
346db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
351db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3534a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3595167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3675167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
369db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
373db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
377db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
378db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
379db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
380db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
381db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
382db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4044a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
412faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
413faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
414faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
415faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
418a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4215167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
426faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4304a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4340a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4355167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4365167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4370a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
439db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
440db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
441faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
442db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
445db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
446faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
448faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
450a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
451a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
4539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
4549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
4569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
4579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
458692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
4599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
4609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
4624a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mEventThread = new EventThread(vsyncSrc, *this);
4639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
4654a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mSFEventThread = new EventThread(sfVsyncSrc, *this);
4669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
467a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
46841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        // set EventThread and SFEventThread to SCHED_FIFO for minimum jitter
46941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
47041a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        param.sched_priority = 1;
47141a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, &param) != 0) {
47241a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for EventThread");
47341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
47441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
47541a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
47641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
47741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
47841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
47941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
4809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
4839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
484f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
4859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc = new HWComposer(this);
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
490b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
493875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
494875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
495a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
496da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
497da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
498da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
501a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
502a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
503d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
504d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
505d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
50692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
50792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5088630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
50913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
51013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
51113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
5124e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
5134e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
514a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
515a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
5183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5193ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
520a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
521a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
522a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
523a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
524a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
525a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
526875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
527875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
528a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
529a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
530875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
531875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
532a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
533a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
535d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
536582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5372adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
538134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
539097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
541134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
542134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
54523e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5497aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5507aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5517aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
552692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5539e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
554692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
562c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5638b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5648b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5658b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5668b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5678b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5688b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5708b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5718b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5728b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5758b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5798b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5801604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
5847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
5857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
5879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
5887f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5897f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
5907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
5917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
5927f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6147f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
6169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
6177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6187f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
62091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
6219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
62291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
62391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
62491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
62591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
62691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
62791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
62891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
62991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
63091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
63191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
63291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
63391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
6359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
64028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
6418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
645dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
64689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
64767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
64867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
64967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
65067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
65167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
65267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
65367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
65467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
65567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
65667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
65767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
65867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
66024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
66124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
66224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
66324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
66424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
6657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
666dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6766c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6826c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
6846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
6856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
6866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
6886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
6896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
6906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
6916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
6926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
6936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
6946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
6956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
6966c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
6977306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
6987306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
699784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
7009ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7017306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
70228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
7037306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7077306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
719888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
720c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
72128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
72228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
72328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
72428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
72528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
72628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
72728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
72828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
72928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
73028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
73128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
73228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
73328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
73428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
73528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
73628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
73728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
73828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
73928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
74028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
74128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
74228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
74328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
74428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
74528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
74628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
74728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
74828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
74928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
75028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
75128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
75228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
75328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
75428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
75528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
75628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
75728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
75828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
75928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
76028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
76128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
76228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
76328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
76428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
76528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
76628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
76728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
76828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
76928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
816c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
817d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
818d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
819d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
820d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
821d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
822d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
823d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
824d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
825d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
826d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
827d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
828d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
829c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
830c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
831c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
832c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
833c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
834c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
835c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
836c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
837c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
838c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
839c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
840c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
841c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
842c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
843c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
844c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
845c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
846c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
847c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
848c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
849c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
850d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
851d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
852d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
8538aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
854bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
855bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
85799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
85899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
85999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
86099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
86699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
86799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
86899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
87199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
875c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
87699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
87799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
87899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
880c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
88199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
88299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
88399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
88499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
88599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
88699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8884f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
8894f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
8904f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
8914f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
89299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
894faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
895faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
896948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
897faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
898d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
899d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
900faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
90143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
902faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
903faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
904948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
905faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
906faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
907948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
908948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
909948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
9100a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
9110a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
912948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
913948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
914948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
9159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
9169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
917faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
918faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
919faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
920faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
921faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
922faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
923d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
924d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
925faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
926faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
927faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
928faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
929948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
931faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
932d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
933d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
934faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
935faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
936faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
937948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
938948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
939948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
940faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
941faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9424a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
9434a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
9444a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
9450a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
9464a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
9474a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
9484a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
9499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
950d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
951faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
952d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
953d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
954d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
955d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
956faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
957148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
958d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
959d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
960d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
961d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
962d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
963d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
964148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
965148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
9669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
9679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
9689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
9699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
9709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
9729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
9739e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
9749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
9759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
9769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
9779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
9799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
9809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer,
9819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                new GraphicBufferAlloc());
9829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
9849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
9859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
9869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
9879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
9889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
9899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
9909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
9919e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
992692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
9939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
9949e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
995692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
996692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
9979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
9989e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
9999e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10009e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
10013ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
10028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10038630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1005faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
10069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
10079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
10088630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10098630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
10111c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
101299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
10136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
10145018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
10155018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
10165018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence->getSignalTime() == INT64_MAX;
10175018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1018c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
10195018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
10205018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
10215018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
10225018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
10236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
10246b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
10255878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
10266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
10275878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
10285878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
10295878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
10306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
10316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
10326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
10336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
10346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
10356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
10366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
10376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10416b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1042e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
10434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
104487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
10456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
10464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
10484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10506b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1051cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
10526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
10534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10543a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
10554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1056cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
105714cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
105840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
105905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
106005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    preComposition();
106105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
106205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
106305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
106405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
106505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    postComposition(refreshStartTime);
106605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
106705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1068bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1069bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1070bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1071bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1072bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1073bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1074bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
107514cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Release any buffers which were replaced this frame
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        layer->releasePendingBuffer();
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1081cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1082cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1083cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1084cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1085cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1086cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1087cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1088cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1089cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1090cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1091cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
10922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1093cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1094cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1095cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1096cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1097cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1098cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1099cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1100cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
11013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
11023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
11033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1104da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1105cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1106cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1107cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1109cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1110cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1111cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1112cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1113cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1114bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
11159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
11167bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
11177bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
11187bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
11197bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
11207bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
11217bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
11229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
11239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1124bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1125cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1126cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1127cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
1128cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
11299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
11309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
11319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1132cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
11331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
11341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1135cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
11361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
1137cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1138cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1139cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1140cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1142cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1143cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1144a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
114540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1146cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
11479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
11489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
11499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
11511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1152cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1153e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool frameLatched = layers[i]->onPostComposition();
1154e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
1155e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(layers[i]->getName().string(),
1156e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    layers[i]->getOccupancyHistory(false));
1157e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
1158cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
11594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
11609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    sp<Fence> presentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1161faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1162faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
1163faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1164faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1165faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1166948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1167faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1168faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1169faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1170b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
11715167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
11722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1173faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1174faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1175faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1176faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
117740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mFenceTracker.addFrame(refreshStartTime, presentFence,
117840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
117940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
11804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
11814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
11824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
1183a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
11844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
11854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
11864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
11874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
11889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
11899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
11904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
11914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
11924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
11934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1194b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1195b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1196b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1197b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1198b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1199b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1200b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1201b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1202b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1203b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1204b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1205b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1206b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1207b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1208b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1209b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1210b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1211b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1212b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1213b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
12179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
12199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1220cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
122152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1222cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
122387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
122487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1225ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
12261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
122792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1228ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1229ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
12309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Vector<sp<Layer>> layersSortedByZ;
12319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
12329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Transform& tr(displayDevice->getTransform());
12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect bounds(displayDevice->getBounds());
12349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (displayDevice->isDisplayOn()) {
12351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
12369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getLayerStack(), dirtyRegion,
12379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        opaqueRegion);
12387e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
12391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
1240ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
12411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
12421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
12439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (s.layerStack == displayDevice->getLayerStack()) {
1244a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1245a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1246a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1247a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1248ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
12499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
12509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // Clear out the HWC layer if this layer was
12519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // previously visible, but no longer is
12529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
12539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    nullptr);
1254ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
125587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
125687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
12573b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
12589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
12599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.set(bounds);
12609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.subtractSelf(
12619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    tr.transform(opaqueRegion));
12629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->dirtyRegion.orSelf(dirtyRegion);
12633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
12643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1265cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
12663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1267cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
12689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
12709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1271028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1272b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1273b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1274b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1275b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1276b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1277b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1278b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1279b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1280b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1281b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1282b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1283b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1284b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1285b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1286b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1287b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1288b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1289b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1290b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1291b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1292b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
12937143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1294b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1295b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1296b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1297b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1298028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1299028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
13009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
13019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
13029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
13039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
13059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
13069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
13079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
13089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
13099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool foundLayerWithoutHwc = false;
13109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                for (auto& layer : currentLayers) {
13119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
13129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
13139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
13149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
13159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
13179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            foundLayerWithoutHwc = true;
13189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1319a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1320a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1321a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
13229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    layer->setGeometry(displayDevice);
13239f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
13249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
132503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
132603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
132703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
132803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
13299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
133003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
13319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
13339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
13389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
13409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
13419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
13429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
13439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
13449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
13459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
13469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
13479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
134838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
134952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
13509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
13519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
13529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13547bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
13557bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
13567bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
13577bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
13587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
13597bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
13609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
13629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1363cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
136452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1366cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
13679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
13689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
136952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
137092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
13722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1373cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1374cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
137502b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
137602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
137702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
137802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1379cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1380cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1381cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
138287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
13834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
138452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1389841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
13909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1391b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1392a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1393a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1394c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
13959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
13977bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
13987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
13997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->commit(hwcId);
14039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14042dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayId == 0) {
14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // Make the default display current because the VirtualDisplayDevice
14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // code cannot deal with dequeueBuffer() being called outside of the
14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // composition loop; however the code below can call glFlush() which
14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // is allowed to (and does in some case) call dequeueBuffer().
14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
14149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
14189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
141952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
14219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1424ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1425e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1426e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1427a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1428a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
14296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
14306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
14316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
14326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
14336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1438841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1439841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
14407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
14417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
14427cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
14437cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
14447cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
14457cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1446ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1447ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1448ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1449ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1450ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1451ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1452ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1453ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1454ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1455ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
145787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1458ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1459ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1460ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1461ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1462ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
14633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
14663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
14673d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
14717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    for (size_t i = 0; i < count; ++i) {
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        currentLayers[i]->notifyAvailableFrames();
14737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
148213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
14933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
149792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
149892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
149992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
150292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
150492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
150593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
150692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
150792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
150892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
150992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
151092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
151192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
151492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
15153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
151627ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
151727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
151827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
151902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1520875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
152102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
152202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
152302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
15249e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
15257adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
152602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
152792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
152892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
152992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
153092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
153192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
15333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1534097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1535097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
15361474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
153893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
153993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
154093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
154102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
154202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
154302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
154493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
154593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
154693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
154793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
154893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
154992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
155093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1551db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
155293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
155393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
155493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
155593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
155600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
155700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
155800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
155900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
156000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
15614fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
156293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
156347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
156447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
156547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
156692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
156792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
156892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
156992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
157092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
157192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
157292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1574e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1575cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
157699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1577db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1578b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1579b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
158070982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
158170982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                            new GraphicBufferAlloc());
1582db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
15839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
158499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
158502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
158602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
158702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
158899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1589db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
15901f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int width = 0;
15911f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int status = state.surface->query(
15921f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_WIDTH, &width);
15931f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
15941f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query width (%d)", status);
15951f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int height = 0;
15961f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            status = state.surface->query(
15971f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_HEIGHT, &height);
15981f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
15991f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query height (%d)", status);
16005cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            int intFormat = 0;
16015cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            status = state.surface->query(
16025cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                                    NATIVE_WINDOW_FORMAT, &intFormat);
16035cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            ALOGE_IF(status != NO_ERROR,
16045cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                                    "Unable to query format (%d)", status);
16055cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            auto format = static_cast<android_pixel_format_t>(
16065cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                                    intFormat);
16071f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza
16085cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            mHwc->allocateVirtualDisplay(width, height, &format,
16099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    &hwcId);
16109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
16115cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
16125cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
16139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
16149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
16159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
16169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
1617db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1618db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
161947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
162099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
162199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1622cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1623cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1624cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1625cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
16269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
16279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            hwcId = DisplayDevice::DISPLAY_EXTERNAL;
16289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            dispSurface = new FramebufferSurface(*mHwc,
16299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    DisplayDevice::DISPLAY_EXTERNAL,
16309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    bqConsumer);
16319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            producer = bqProducer;
16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
16339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            ALOGE("Attempted to add non-external non-virtual"
16349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    " display");
16359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        }
1636cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1637cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1638cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
163999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1640cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
16419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                state.type, hwcId, state.isSecure, display,
16429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                dispSurface, producer,
164305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1644cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1645cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
16464fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
16478dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1648cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
16499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
16507adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
16511c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
165293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
165392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
165492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
16563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
16598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
16608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
16618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
16628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
16648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
16658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
16678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
16688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
16698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
16718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
16728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
16748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
16758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
16768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
16778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
16798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
16808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
16818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
16828430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
16838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
168413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
16851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
16868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
16878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
16888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
16898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
16908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
16918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
16928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
16948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
16958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
16968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
16978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
169891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
16998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
17008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
17018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
17028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
17038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
170491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
170591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
170691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
170791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
170891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
170991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
171091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
171191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
17128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
171391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
17148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
17158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
17168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
17193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
17203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
17231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
17243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
17253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
17263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
17273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
17283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
17293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
17303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
17313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
17323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
17331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
17343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
17351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
17363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
17373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
17383559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
17393559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
17403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
17411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
17423dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                Region visibleReg = s.active.transform.transform(
17431501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
17441501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
17450aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
175003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
175103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
175203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
175303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
175403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
175503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
17569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
17589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
175903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
176003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
17619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
17629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
176403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
176503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
17664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
17674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
17684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
17694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
17704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
17714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
17724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
1773e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
1774e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    mLayersPendingRemoval[i]->getOccupancyHistory(true));
17754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
17764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
17774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
17784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
17794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
17804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
17814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
17824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
17834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
17844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
17852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
17862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
17874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
179187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
179287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1794841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
17959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
1796841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
180513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
18081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
181187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
181287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
181387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1814ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1815ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1816ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1818ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1819ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1820ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1821ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1822ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1823ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1824ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1826ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1827ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1828ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1829ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1830ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1832ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1833a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1834a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1835a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1836a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1837a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1838a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1839a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1840a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1841a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1842a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1843ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1844ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1845da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
18464125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
18473dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            Rect bounds(s.active.transform.transform(layer->computeBounds()));
1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1849ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1850ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1851ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
18523dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                    const Transform tr(s.active.transform);
185322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
185422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
185522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
18564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
185722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
185822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
185922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
18604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1861ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1863ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
18643dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                const int32_t layerOrientation = s.active.transform.getOrientation();
18659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
1866ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1867ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1868ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1869ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1873ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1874ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1875ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1876ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1877ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1878ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
18874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1890a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1894ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1900ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1901a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1902ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
19034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
19044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
191187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
19158b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1916a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1919a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1920a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
192787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
192892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
19304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
19314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
193292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
193392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
193487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
193587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
19366b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
19399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
19404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
194199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
19431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
19446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
194551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
194651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
194751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
194851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
194951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
195051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
195151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
195251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
195351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
195451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
195551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
19561eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
19576b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
19586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
19596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
19609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mLayersWithQueuedFrames.push_back(layer.get());
1961ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
1962ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
19636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
1964ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
1965ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
19666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
196751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
19689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
196987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
1970ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
19711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
197287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
19744da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
19753b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
19766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
19786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
19796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
19809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
19816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
19826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
19836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
19859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1988ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1989ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
19909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
1991ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1992ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
199399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1994cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
199587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19977143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
19987143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
19997143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
20007143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
20017143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
20027143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
20039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
20047143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
20057143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
20067143316af216fa92c31a60d4407b707637382da1Dan Stoza
20079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
20089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
200987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
201087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2011b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
20124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
20150f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
201629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
201729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
201829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
20194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
2020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
20210f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
202229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2023df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
202495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
20250f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
20264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
2027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
202829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
20294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
20304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (!doComposeSurfaces(hw, dirtyRegion)) return;
2035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20369c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
20374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2038da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2039da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2040da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
2041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
20449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
20479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
20499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
20509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
20519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
20529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
20539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
20549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
20559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
20569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
20579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
20589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
20609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2061a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
20629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2063c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
20649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
20653f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
20663f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
20673f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
20683f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
20693f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2070c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2071a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2072a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
20739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
20749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2075b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2076b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
20783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2079b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
20809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2081b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2082766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
20839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2084766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2085766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2086766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2087766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
20889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2089766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2090766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
20919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2092766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2093766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2094766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2095766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2096b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
209787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2098b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
20999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2100b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2101a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2102f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2104766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2105f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2106f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
21079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
21089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2109f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2110f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2111f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2112f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
21133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2114f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
21159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
21169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
21173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2118f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2119f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
212085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
21214b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
212285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
212385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
212485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
21254b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
21269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
21279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
21289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
212985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
21309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
21319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
21329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
21339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
21349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
21369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
213785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
21389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
21409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
21419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2142ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
21439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
21449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
21459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2146cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2147cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
21489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->clearWithOpenGL(displayDevice, clip);
2149cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
215085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
215185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
21529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
215485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2155a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
21569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2157da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2158cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
21599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
21609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2161a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
21629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
216385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
216485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
216585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
21669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
216785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
21689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
216985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
21709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
217185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
21724b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
21734b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2174f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21759f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
21769f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
21779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
21789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2179f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
21809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
21813f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
218555801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
21863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
21873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2191ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
21926710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
219313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
21941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
21957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
21967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
21977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
21987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
21997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
22007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
22017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mCurrentState.layersSortedByZ.add(lbc);
22027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
22037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
22047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
220596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2206ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
22074f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
22087d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
220996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
221096f0819f81293076e652792794a961543e6750d7Mathias Agopian
22113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
221296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
221313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
22156710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
2216076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
22176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
2219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
22203d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
2221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2223c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
2224dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2225dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2226dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
22273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
223499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
22408b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
22418b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
22428b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
22438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
22447c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2245698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
224628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
22482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
22492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
22502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
22512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
22527c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
22532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
22542d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
22557c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
22567c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
22577c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
22582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
22592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
22602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
22612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
22622d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
22632d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2264e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2265e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2268b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2269b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2271698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2272698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2273d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2274d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2275d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2276d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2277d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2278d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2279d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2280d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2281097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2282d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2283d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2284d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2285d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2286d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2287d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2288d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2289d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2290698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2291386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
22922a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
22932a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
22942a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
22952a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
22962a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
22972a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
22982a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
229928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2300386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
230128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2302698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2303386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2304386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2305386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
23062d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
23072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
23092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2310386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
23112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2312386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2313386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2314386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2315386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
23162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
23172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2318386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2319386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2320cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2324e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2325e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
23269a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
23279a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
23289a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
23299a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2330e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
23319a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
23323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2333e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2335097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2336e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2338e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2339e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2342e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2343e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2344e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
234600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2347e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2348e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2349e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2350e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2351e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2352e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2353e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2354e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2355e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2356e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2357e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2358e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2359e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
236047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
236147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
236247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
236347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
236447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
236547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
236647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
236747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
236847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
236947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2370e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2371e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2372e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2373e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2374e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2375e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2376e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2377e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2378e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
237913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2380e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2381e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
238299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
238399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
238599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2386e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
238782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2388e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2389e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2390e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2391e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
239247db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayer(s.z) && idx >= 0) {
2393e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2394e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2398e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2399e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2400e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2401e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2402e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
24069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2417231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2420e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2421e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
242299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2425acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2426acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2427acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2428acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
243247db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
2433e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2434e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2436e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2439e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
24407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
24417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            layer->deferTransactionUntil(s.handle, s.frameNumber);
24427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
24437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
24447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2445c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2446c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2447c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2448c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2449c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
24544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
24550ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
24560ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
24574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
24584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
24616e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2462921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
24636e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
24644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
24656e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
24668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
24674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
24684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
24694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
24704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
24713165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
24723165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
24734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
24744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
24754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
24773165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
24784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
24794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
24804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
24814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
24824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
24834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24877d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
24887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
24907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
24917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    result = addClientLayer(client, *handle, *gbp, layer);
24927d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
24937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
24947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
24957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
24967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
24974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
25014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
25024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
250592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
25118f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
25164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
25174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
25184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2519b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
25234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
25274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
25284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
25314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2532b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
25334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2534118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2535118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2536ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
25379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
25386710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
25396710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
25406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
25416710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
25426710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
25436710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
25446710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
25459a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
25469a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
25479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
25489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
254913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
25526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2553ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
255413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2555ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
25566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2557e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2559ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2560ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2563b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2564b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
256513a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
256601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
256713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
256813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
256913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
257001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
257101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2572692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
257301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
257413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
25754c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
25764c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
257747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
257847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
257913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
258013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
25812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
25826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
25839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
25849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
25856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
258613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
258713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
258813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
258913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
259013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
259113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
259213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
259313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
259413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
259513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
259613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
259713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
259813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
259913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
260013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
260113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
26022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
26032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
26042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
26052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
26062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
26072c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
260813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
26092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
26102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2611c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2612c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2613c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
26142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
26152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
26162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
26172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
26182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2619c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
26202c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
26212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2622c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2623c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2624c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2625948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2626c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2629b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
26302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
26312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2632c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2633948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2634948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2635cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2636cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2637cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2638c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
26392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
26402c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
26412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
26422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
26432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2644b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
26482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2649db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2650db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
26512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2652b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
26532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
26552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2656b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
26572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2658db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
26592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
26607306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
26619e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
26622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
26632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2664db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
26652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2666db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2667b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2668b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2669b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
26702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2671db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2672b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2673b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2674b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2675b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
267999b49840d309727678b77403d6cc9f920111623fMathias Agopian
2680bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2681bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2682bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2683bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2684bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
268574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2686bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2688fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
26899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
26909795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2691fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2692fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
26939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2694fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2695fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2696fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
26979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
26989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
269982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
270082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
270125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
270225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
270325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
270425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
270525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
270674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
270735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
270825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
270925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
271025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
271125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
271282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
271374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
271435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
271582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
271625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
271725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
271825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
271925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
272074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
272135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
272225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2723c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2724c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2725c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2726c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2727c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2728c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2729c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2730b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2731b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2732b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2733b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2734b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2735b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2736b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
273740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
273840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
273940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                    (args[index] == String16("--fences"))) {
274040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
274140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                mFenceTracker.dump(&result);
274240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
274340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
2744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
27451b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
274682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
274774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
274882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
274948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
275082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
275182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
275248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
275382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
275482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
275582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
275682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
275748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2758c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2759c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
276025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
276125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
276225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
276325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
276413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
276574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
276625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
276725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
276825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
276982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
277074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
277182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
277282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
277382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
277482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
277582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
277682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
277748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
27789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
27799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
278086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
27814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
27824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2783d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
27844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
27854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
27864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
27874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
278813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
27894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2790d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
27914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
279282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
279382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
279482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2795ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
279625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2797c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
279825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
279925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
280025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
280125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
280225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
280325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
280425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
280525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
280625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
280725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
280813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
280925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2810d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
281125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
281225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
28134b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2814d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
281525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
281625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
28176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
28186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
28196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
28206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
28216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
28226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
28236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
28246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
28256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
28266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
28276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
28286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
28296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
28304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
28314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
28324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
28334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
28344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
28354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
28364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
28384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
28394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
28414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
28424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
28444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
28454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
28464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2847b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2848b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2849b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2850b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2851b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2852b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2853b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2854b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2855b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2856b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2857b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2858b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2859b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2860b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2861b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2862b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2863b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2864e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
2865e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
2866e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2867e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
2868e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
2869e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
2870e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
2871e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2872e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
2873e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
2874e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
2875e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
2876e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2877e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
2878e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
2879e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2880e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2881e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2882e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
2883e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
2884e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
2885e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
2886e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2887e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
2888e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
2889e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
2890e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
2891e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
2892e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
2893e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
2894e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2895e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
2896e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
2897e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
2898e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
2899e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
2900e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
2901e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
2902e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
2903e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
2904e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2905e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
2906e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
2907e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
2908e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
2909e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
2910e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
2911e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
2912e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2913e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
2914e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2915e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2916e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
291774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
291874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
291982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
29203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
29213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
29223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
29233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
29243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
29253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
29263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
29273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
29283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
292982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
293082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
293182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
293282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
293382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
293482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2935bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
293682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
29374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
29384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
29393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
29403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
29414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
29423e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
29434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
29444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
29454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
29464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
29474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
29483e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2949ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
29503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2951ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2952ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2953ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
29549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
29559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
295641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
295741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
295841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
295924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
296024cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
29619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
29629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
296341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
296441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
2965b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
2966b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2967b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
2968b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2969b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
2971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
29724803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
297382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
297482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
297582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
297682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
29773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
297886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
29793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
298082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
298113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
29823e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
298382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2984bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
298582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
29865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
29875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
29885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
29893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
299086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
29913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
29925f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
29935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
299474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
29955f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
29965f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
29975f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
299882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
299982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
30001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
30013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
300274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
30033e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30041b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3005888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
30064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3007ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
30083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
30093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
30103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
30113e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3013ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3014ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3015875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
30169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
30174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
30182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
30192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
302074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
302182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
302282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3023c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
302482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
302582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3026ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3027ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3028ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
302982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
303082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3031c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
30329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
30339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
30349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3035ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
303682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
303774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
303882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
303982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
304074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
304182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
304282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
304382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
304482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
304582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
304674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
304782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
304882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
304982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
305082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
30513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
305274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
30533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
30559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
30569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
305774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
305882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
305982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
306082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
306182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
306282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
306382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
306613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
306748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3068db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
306948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
307048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
307148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
307248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
307348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
307448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
307548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
307648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
307748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
307848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
307948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
308048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
308148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3082cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3083cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
308463f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
308563f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
308663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
308763f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
308863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
308963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
309063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
309163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
309263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
309324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
309463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
309563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
309663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
309763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
309863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
309963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
310063f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
310163f165fd6b86d04be94d4023e845e98560504a96Keun young Park
3102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
3103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3107041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3108698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
3109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3110d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3111d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
31122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3113c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3118a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
31193bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
312099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
3121e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
3122375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3123375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
31251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
31261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
31271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
31281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
31291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
31301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
31311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
31321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
313399b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
313499b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
3135e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
31361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
31371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
31381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
31391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
31421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3145b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
314699ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3147375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3148375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3149375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3150e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3151375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
315601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
315735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
316253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
316353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
316653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3167cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3168cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3169cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3174cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
31764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
31774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
31784d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
31794d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
318053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
318153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
318253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
318353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
318453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
318553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3186a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3187a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3188a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3189a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3190a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3191a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
319301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3196b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
319712839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
32014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
32024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3203ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3204ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3205ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3206ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3207ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3208ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
32099f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
32109f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
32119f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32129f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
32139f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
32149f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
32169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
32179f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
32199f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
32209f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3221ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3222ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
32239f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3224ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
32259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3226ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3227ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3228ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
32299c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
32309c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
32319c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
32329c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
32339c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
32349c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
32359c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
32369c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
32379c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3238794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
32399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
32409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
32419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
32429c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
32439c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
32449c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
32459c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
32469c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
32479c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
32489c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3250f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3251f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3252f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3253645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3254645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3255f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3256f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3257ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3258ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3259ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3260ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3261ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3262db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3263db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3264db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3265db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3266db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3267db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3268db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3269db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3270db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3271db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
327753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
327887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
327999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
328053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
328153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
328259119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
32832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
32842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
328559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
32862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
32872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
32882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3289b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3290b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3291b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3292b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
32932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
32942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3295b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3296b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3297b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3298b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3299b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3300b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3301b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3302b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3303b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3304b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3305b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3306b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3307b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3308b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
33092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
33102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
33112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
33122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
33132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3314b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
33152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
33162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
33172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
33182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
33202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
33212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
33222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
33232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3325b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3326b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3327b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
33282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
33292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3330c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
33312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
33322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
33332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
33342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3335b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3336b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3337b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3338b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
33392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
33402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
33412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3342b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3343b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3344b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
33452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
33462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
33472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3348c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
33492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
33502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3352b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
33532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
33542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
33552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3356b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3357b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3358b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3359b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3360097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
33612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3362b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
33632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
33642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
33652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
33662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3368b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3369b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3370b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
337153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3372b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
337353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
337453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
337553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
337653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3377b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3378b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3379b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
33802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
33812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
33822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
33832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
33842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
33852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
33862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3387b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
33882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3389aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
33902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3391b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3392b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3393b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
33942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
33952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
33962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
33972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
34002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3401c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3402c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3403c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
34042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
34062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
34072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
34092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
34102a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34115ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
34125ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
34135ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3414b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
34155ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3416c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3417c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3418c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3419c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3420c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3421c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3422c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3423c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3424c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3425c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3426c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3427c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3428c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3429c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3430c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3431c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3432c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3433c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3434c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3435c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3436c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
34372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
34382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
34392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
34402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3441c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
34422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
34432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3444c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3445c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
34462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3447b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
34482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
34492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
34502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
34512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3452c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3453c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3454b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3455b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3456b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
34572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3458c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
34592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3460c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3461b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3462b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
34632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
34642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
34652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
34662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
34672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
34682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
34692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
34702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3471c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3472c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3473b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3474097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
34752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
34762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
34772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
34782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
34802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
34812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
34822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
34832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
34852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
34862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
34872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3488c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3489b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
34902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
34922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
34932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
34942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
34952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3496118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3497118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3498180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3499180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3500180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3501c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3502180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3503c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3504180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3505180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
35063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3507180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3508180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
350989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
351089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
351189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
35120e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3513180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3514c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3515c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3516c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3517c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3518c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3519c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3520c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3521c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3522c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3523c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3524c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3525be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3526be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3527c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3528c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3529c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3530c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3531be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3532be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3533c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3534c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3535180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
35363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3537180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3538180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3539c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3540c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
35413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3542180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3543180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
35443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3545180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3546180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3547180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3548180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3549180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
35501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3551180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3552180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3553180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3554180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3555c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3556180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3557180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3558180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3559180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3560180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3561180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3562931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3563180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3564180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3565180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
35662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
35672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
35682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3569c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3570c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3571b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
3572b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
357374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3574fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3575fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3576180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
35773502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
35783502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
35793502416204d9dbd905012ee586d8bd145323809fDan Stoza
35803502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
35813502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
35823502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3583180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3584180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3585180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3586180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3587180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3588180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3589180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3590180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3591180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3592180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3593b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
3594b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const LayerVector& layers(mDrawingState.layersSortedByZ);
3595b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const size_t count = layers.size();
3596b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    for (size_t i = 0 ; i < count ; ++i) {
3597b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const sp<Layer>& layer(layers[i]);
3598b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
3599b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
3600b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                state.z <= maxLayerZ && layer->isVisible() &&
3601b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                layer->isSecure()) {
3602b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            secureLayerIsVisible = true;
3603b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
3604b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3605b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
3606b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
3607b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
3608b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
3609b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3610b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
36110aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
36120aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
361383cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
3614605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
3615605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
3616605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
3617605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
3618605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
3619605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
3620605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
3621605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
36220aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
362374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
36245a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
36255a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
36263ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
36273ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
36282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
36300aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
36314ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
36320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
36330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
36342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
36360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
36370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
36380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
36390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
36400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
36410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3642866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
36430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
36440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
36450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
36460aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
36470aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
36483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
36493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
36503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
36513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
36520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
36530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
36540aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
36550aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3656c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3657c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3658c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3659d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3660866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3661866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3662866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3663866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3664866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3665866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
36669707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
36679707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3668866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3669866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3670866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
36712d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3672866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3673866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3674866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3675866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3676866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3677866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
36782d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3679866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3680866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3681866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3682866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3683866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3684866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3685866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3686866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3687866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3688866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3689866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3690866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3691866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3692866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
36932d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3694866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
36952d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
36962d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3697d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3698d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3699d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3700d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3701d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3702d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3703d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3704d555684cb36dfb959694db76962e570184f98838Mathias Agopian
37050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
37060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
37070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
3708f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
3709f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
37100aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
37110aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
37120aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
37130aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
37140aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
371574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3716f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
3717f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
3718f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
3719f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
372074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
37210aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
37220aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
372374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
37240aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
372574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
372674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
372774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
372874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
372974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3730d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3731d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3732fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3733d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3734d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3735d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3736fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3737fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3738fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3739fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3740fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3741fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3742fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3743fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3744fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3745fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3746fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3747fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3748fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3749fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
37509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
3751fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3752fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3753fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3754fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3755fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3756fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3757fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
3758ce796e78a57018f186b062199c75d94545318acaPablo Ceballosbool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
3759ce796e78a57018f186b062199c75d94545318acaPablo Ceballos        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
3760ce796e78a57018f186b062199c75d94545318acaPablo Ceballos    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
3761ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
3762ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
37631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
37641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3765921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3766921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3767921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3768921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
376913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3770921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3771921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3772921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3773921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3775be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
377613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
377713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3778be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
37791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
37801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3781be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3782be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3783be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
37841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
37851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3786be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3787be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3788be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3789be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3790921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3791921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3792921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3793921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
37943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
379553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    : type(DisplayDevice::DISPLAY_ID_INVALID),
379653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      layerStack(DisplayDevice::NO_LAYER_STACK),
379753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      orientation(0),
379853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      width(0),
379953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      height(0),
380053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      isSecure(false) {
380153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos}
380253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos
380353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo CeballosSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(
380453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDevice::DisplayType type, bool isSecure)
380553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    : type(type),
380653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      layerStack(DisplayDevice::NO_LAYER_STACK),
380753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      orientation(0),
380853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      width(0),
380953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      height(0),
381053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      isSecure(isSecure) {
3811da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3812da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3813b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
38147303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3815b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
381696f0819f81293076e652792794a961543e6750d7Mathias Agopian
3817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
38183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
38213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
38223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
38233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
38253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
38263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3827