SurfaceFlinger.cpp revision 598f6d5429b290f33107ef678328914b99c8312e
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");
1863cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza
1873cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza    property_get("debug.sf.disable_hwc_vds", value, "0");
1883cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza    mUseHwcVirtualDisplays = !atoi(value);
1893cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza    ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
199a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
200a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
201a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
204c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
20599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
20699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
20799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
20913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
21099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
212a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
21399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
21499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2157e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
21896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
21996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
22096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
22196f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
227dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
24653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2478dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
2739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
274692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
275692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
276692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
277692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
27853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
279692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
280692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
281692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2839e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
288e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2919a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
300a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3013330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
311a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
312a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
313a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3140a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3150a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3160a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3170a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
324921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
327921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
328921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
330921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
332921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3385167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3394a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3404a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3410a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3420a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3434a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3444a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
345db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
346db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
347db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
348db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
349db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
350db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
355db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3574a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3635167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3715167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
373db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
377db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
379faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
380faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
381db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
382db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4084a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
416faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
422a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
431faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4344a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4354a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
436faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4380a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4405167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4410a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
442faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
445faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
446db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
447db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
448db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
449db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
450faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
451faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
4579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
4589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
4609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
4619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
462692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
4639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
4649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
4664a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mEventThread = new EventThread(vsyncSrc, *this);
4679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
4694a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mSFEventThread = new EventThread(sfVsyncSrc, *this);
4709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
471a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
472acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
47341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
47435520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
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
4799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
4809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
483f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
4849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
4859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc = new HWComposer(this);
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
489b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
493875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
495da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
496da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
497da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
500a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
501a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
502d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
503d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
504d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
50592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
50692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
50813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
50913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
51013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
5114e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
5124e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
513a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
514a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
5173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
519a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
520a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
521a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
522a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
523a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
524a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
525875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
526875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
527a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
528a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
529875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
530875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
531a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
532a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
534d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
535582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
537134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
538097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5396710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
540134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
541134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
54423e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5487aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5497aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5507aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
551692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5529e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
553692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
561c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5628b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5638b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5648b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5658b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5668b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5678b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5688b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5708b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5718b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5728b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5758b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
5847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
5877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5887f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
5897f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
5907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
5917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
5927f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6121604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
6167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
61991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
6209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
62191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
62291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
62391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
62491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
62591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
62691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
62791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
62891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
62991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
63091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
63191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
63291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
63928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
6408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
644dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
64589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
64667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
64767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
64867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
64967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
65067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
65167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
65267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
65367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
65467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
65567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
65667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
65767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
65924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
66024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
66124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
66224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
66324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
6647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
665dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6766c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6826c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
6836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
6846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
6856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
6876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
6886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
6896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
6906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
6916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
6926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
6936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
6946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
6956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
6967306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
6977306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
698784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
6999ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7007306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
70128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
7027306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7036c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7067306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
718888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
719c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
72028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
72128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
72228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
72328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
72428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
72528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
72628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
72728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
72828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
72928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
73028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
73128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
73228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
73328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
73428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
73528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
73628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
73728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
73828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
73928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
74028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
74128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
74228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
74328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
74428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
74528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
74628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
74728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
74828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
74928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
75028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
75128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
75228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
75328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
75428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
75528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
75628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
75728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
75828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
75928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
76028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
76128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
76228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
76328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
76428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
76528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
76628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
76728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
76828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
76928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
77028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
815c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
816d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
817d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
818d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
819d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
820d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
821d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
822d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
823d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
824d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
825d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
826d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
827d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
828c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
829c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
830c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
831c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
832c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
833c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
834c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
835c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
836c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
837c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
838c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
839c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
840c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
841c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
842c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
843c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
844c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
845c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
846c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
847c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
848c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
849d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
850d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
851d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
8528aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
853bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
854bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
85699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
85799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
85899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
85999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
86199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
86599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
86699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
86799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
86899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
86999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
87099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
87199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
874c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
87599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
87699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
87799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
87899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
88099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
88199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
88299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
88399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
88499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
88599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8874f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
8884f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
8894f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
8904f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
89199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
893faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
894faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
895948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
896faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
897d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
898d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
899faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
90043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
901faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
902faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
903948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
904faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
905faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
906948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
907948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
908948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
9090a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
9100a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
911948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
912948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
913948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
9149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
9159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
916faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
917faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
918faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
919faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
920faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
921faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
922d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
923d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
924faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
925faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
926faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
927faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
928948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
929faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
931d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
932d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
933faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
934faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
935faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
936948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
937948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
938948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
939faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
940faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9414a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
9424a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
9434a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
9440a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
9454a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
9464a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
9474a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
9489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
949d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
950faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
951d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
952d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
953d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
954d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
955faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
956148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
957d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
958d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
959d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
960d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
961d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
962d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
963148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
964148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
9659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
9669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
9679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
9689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
9699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
9719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
9729e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
9739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
9749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
9759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
9769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
9789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
9799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer,
9809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                new GraphicBufferAlloc());
9819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
9829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
9839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
9849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
9859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
9869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
9879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
9889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
9899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
9909e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
991692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
9929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
9939e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
994692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
995692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
9969e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
9979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
9989e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
9999e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
10003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
10018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
10059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
10069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
10078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10088630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
10101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
101199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
10126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
10135018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
10145018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
10155018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence->getSignalTime() == INT64_MAX;
10165018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1017c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
10185018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
10195018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
10205018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
10215018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
10226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
10236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
10245878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
10256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
10265878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
10275878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
10285878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
10296b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
10306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
10316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
10326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
10336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
10346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
10356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
10366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10406b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1041e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
10424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
104387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
10446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
10454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
10466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
10474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10496b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1050cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
10516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
10524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
10533a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
10544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1055cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
105614cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
105740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
105805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
105905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    preComposition();
106005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
106105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
106205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
106305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
106405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    postComposition(refreshStartTime);
106505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
106605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1067bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1068bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1069bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1070bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1071bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1072bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1073bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
107414cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Release any buffers which were replaced this frame
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        layer->releasePendingBuffer();
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1080cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1081cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1082cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1083cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1084cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1085cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1086cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1087cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1088cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1089cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1090cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
10912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1092cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1093cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1094cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1095cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1096cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1097cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1098cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1099cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
11003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
11013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
11023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1103da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1104cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1105cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1106cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1107cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1109cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1110cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1111cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1112cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1113bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
11149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
11157bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
11167bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
11177bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
11187bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
11197bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
11207bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
11219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
11229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1123bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1125cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1126cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
1127cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
11289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
11299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
11309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1131cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
11321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
11331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1134cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
11351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
1136cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1137cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1138cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1139cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1140cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1142cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1143a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
114440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1145cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
11469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
11479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
11489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
11501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1151cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1152e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool frameLatched = layers[i]->onPostComposition();
1153e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
1154e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(layers[i]->getName().string(),
1155e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    layers[i]->getOccupancyHistory(false));
1156e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
1157cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
11584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
11599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    sp<Fence> presentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1160faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1161faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
1162faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1163faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1164faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1165948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1166faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1167faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1168faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1169b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
11705167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
11712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1172faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1173faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1174faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1175faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
117640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mFenceTracker.addFrame(refreshStartTime, presentFence,
117740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
117840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
11794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
11804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
11814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
1182a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
11834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
11844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
11854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
11864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
11879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
11889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
11894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
11904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
11914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
11924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1193b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1194b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1195b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1196b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1197b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1198b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1199b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1200b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1201b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1202b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1203b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1204b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1205b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1206b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1207b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1208b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1209b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1210b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1211b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1212b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
12169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
12189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1219cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
122052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1221cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
122287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
122387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1224ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
12251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
122692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1227ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1228ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
12299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Vector<sp<Layer>> layersSortedByZ;
12309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
12319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Transform& tr(displayDevice->getTransform());
12329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect bounds(displayDevice->getBounds());
12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (displayDevice->isDisplayOn()) {
12341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
12359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getLayerStack(), dirtyRegion,
12369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        opaqueRegion);
12377e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
12381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
1239ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
12401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
12411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
12429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (s.layerStack == displayDevice->getLayerStack()) {
1243a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1244a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1245a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1246a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1247ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
12489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
12499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // Clear out the HWC layer if this layer was
12509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // previously visible, but no longer is
12519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
12529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    nullptr);
1253ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
125487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
125587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
12563b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
12579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
12589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.set(bounds);
12599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.subtractSelf(
12609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    tr.transform(opaqueRegion));
12619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->dirtyRegion.orSelf(dirtyRegion);
12623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
12633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1264cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
12653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1266cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
12679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
12699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1270028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1271b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1272b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1273b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1274b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1275b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1276b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1277b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1278b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1279b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1280b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1281b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1282b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1283b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1284b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1285b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1286b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1287b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1288b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1289b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1290b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1291b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
12927143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1293b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1294b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1295b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1296b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1297028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1298028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
12999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
13009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
13019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
13029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
13049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
13059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
13069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
13079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
13089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool foundLayerWithoutHwc = false;
13099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                for (auto& layer : currentLayers) {
13109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
13119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
13129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
13139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
13149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
13169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            foundLayerWithoutHwc = true;
13179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1318a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1319a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1320a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
13219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    layer->setGeometry(displayDevice);
13229f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
132403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
132503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
132603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
132703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
13289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
132903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
13309f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
13329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
13389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
13409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
13419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
13429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
13439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
13449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
13459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
13469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
134738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
134852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
13499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
13509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
13519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
13529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13537bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
13547bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
13557bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
13567bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
13577bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
13587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
13599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
13609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1362cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
136352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1364cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
13669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
13679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
136852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
136992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
13712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1372cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1373cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
137402b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
137502b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
137602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
137702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1378cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1379cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1380cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
138187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
13824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
138352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1388841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
13899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1390b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1391a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1392a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1393c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
13949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
13967bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
13977bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
13987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
13999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->commit(hwcId);
14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14032dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayId == 0) {
14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // Make the default display current because the VirtualDisplayDevice
14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // code cannot deal with dequeueBuffer() being called outside of the
14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // composition loop; however the code below can call glFlush() which
14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            // is allowed to (and does in some case) call dequeueBuffer().
14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
14149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
141852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1423ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1424e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1425e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1426a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1427a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
14286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
14296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
14306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
14316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
14326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
143587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1437841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1438841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
14397cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
14407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
14417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
14427cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
14437cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
14447cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1445ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1446ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1447ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1448ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1449ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1450ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1451ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1452ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1453ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1454ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
145687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1457ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1458ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1459ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1460ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1461ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
14623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
14653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
14663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
14707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    for (size_t i = 0; i < count; ++i) {
14717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        currentLayers[i]->notifyAvailableFrames();
14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
14737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14793559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
14923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
149692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
149792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
149892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
150192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
150392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
150493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
150592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
150692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
150792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
150892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
150992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
151092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
151392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
15143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
151527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
151627ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
151727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
151802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1519875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
152002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
152102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
152202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
15239e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
15247adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
152502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
152692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
152792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
152892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
152992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
153092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
15323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1533097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1534097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
15351474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
153793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
153893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
153993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
154002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
154102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
154202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
154393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
154493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
154593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
154693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
154793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
154892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
154993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1550db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
155193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
155293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
155393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
155493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
155500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
155600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
155700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
155800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
155900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
15604fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
156193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
156247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
156347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
156447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
156592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
156692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
156792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
156892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
156992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
157092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
157192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1574cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
157599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1576db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1577b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1578b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
157970982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
158070982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                            new GraphicBufferAlloc());
1581db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
15829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
158399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
158402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
158502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
158602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
158799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1588db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
15893cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                            if (mUseHwcVirtualDisplays) {
15903cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                int width = 0;
15913cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                int status = state.surface->query(
15923cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
15933cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                ALOGE_IF(status != NO_ERROR,
15943cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        "Unable to query width (%d)", status);
15953cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                int height = 0;
15963cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                status = state.surface->query(
15973cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
15983cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                ALOGE_IF(status != NO_ERROR,
15993cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        "Unable to query height (%d)", status);
16003cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                int intFormat = 0;
16013cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                status = state.surface->query(
16023cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
16033cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                ALOGE_IF(status != NO_ERROR,
16043cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        "Unable to query format (%d)", status);
16053cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                auto format = static_cast<android_pixel_format_t>(
16063cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        intFormat);
16073cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza
16083cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
16093cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                                        &hwcId);
16103cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                            }
16119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
16125cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
16135cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
16149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
16159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
16169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
16179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
1618db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1619db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
162047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
162199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
162299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1623cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1624cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1625cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1626cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
16279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
16289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            hwcId = DisplayDevice::DISPLAY_EXTERNAL;
16299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            dispSurface = new FramebufferSurface(*mHwc,
16309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    DisplayDevice::DISPLAY_EXTERNAL,
16319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    bqConsumer);
16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            producer = bqProducer;
16339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
16349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            ALOGE("Attempted to add non-external non-virtual"
16359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    " display");
16369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        }
1637cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1638cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1639cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
164099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1641cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
16429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                state.type, hwcId, state.isSecure, display,
16439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                dispSurface, producer,
164405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1645cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1646cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
16474fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
16488dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1649cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
16509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
16517adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
16521c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
165393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
165492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
165592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
16573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
16608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
16618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
16628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
16638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
16658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
16668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
16688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
16698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
16708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
16728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
16738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
16758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
16768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
16778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
16788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
16798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
16808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
16818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
16828430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
16838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
16848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
168513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
16861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
16878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
16888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
16898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
16908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
16918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
16928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
16938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
16958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
16968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
16978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
16988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
169991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
17008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
17018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
17028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
17038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
17048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
170591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
170691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
170791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
170891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
170991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
171091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
171191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
171291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
17138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
171491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
17158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
17168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
17178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
17203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
17213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
17241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
17253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
17263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
17273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
17283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
17293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
17303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
17313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
17323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
17333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
17341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
17353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
17361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
17373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
17383559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
17393559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
17403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
17413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
17421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
17433dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                Region visibleReg = s.active.transform.transform(
17441501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
17451501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
17460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
175103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
175203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
175303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
175403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
175503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
175603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
17579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
17599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
176003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
176103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
17629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
17639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
176503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
176603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
17674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
17684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
17694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
17704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
1771598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
17724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
17734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
1774e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
1775e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    mLayersPendingRemoval[i]->getOccupancyHistory(true));
17764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
17774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
17784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
17794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
17804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
17814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
17824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
17834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
17844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
17854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
17862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
17872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
17884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
179287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
179387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1795841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
17969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
1797841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
180287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
180613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
18091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
181287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
181387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
181487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1815ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1816ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1817ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1819ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1820ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1821ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1822ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1823ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1824ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1825ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1827ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1828ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1829ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1830ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1831ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1833ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1834a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1835a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1836a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1837a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1838a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1839a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1840a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1841a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1842a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1843a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1844ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1845ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1846da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
18474125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
18483dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            Rect bounds(s.active.transform.transform(layer->computeBounds()));
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1850ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1851ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1852ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
18533dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                    const Transform tr(s.active.transform);
185422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
185522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
185622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
18574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
185822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
185922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
186022f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1862ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1864ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
18653dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                const int32_t layerOrientation = s.active.transform.getOrientation();
18669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
1867ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1868ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1869ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1870ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1874ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1875ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1876ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1877ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1878ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1879ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
18884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1891a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1894ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1900ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1902a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
19044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
19054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
191287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
19168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1917a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1920a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1921a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
192887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
192992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
19314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
19324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
193392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
193492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
193587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
193687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
19376b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
19409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
19414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
194299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
19441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
19456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
194651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
194751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
194851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
194951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
195051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
195151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
195251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
195351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
195451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
195551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
195651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
19571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
19586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
19596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
19606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
19619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mLayersWithQueuedFrames.push_back(layer.get());
1962ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
1963ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
19646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
1965ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
1966ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
19676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
196851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
19699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
197087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
1971ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
19721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
197387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
19744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
19754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
19763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
19776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
19796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
19806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
19819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
19826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
19836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
19846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
19856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
19869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1989ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1990ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
19919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
1992ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1993ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
199499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1995cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
199687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19987143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
19997143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
20007143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
20017143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
20027143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
20037143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
20049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
20057143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
20067143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
20077143316af216fa92c31a60d4407b707637382da1Dan Stoza
20089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
20099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
201087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
201187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2012b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
20134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
20160f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
201729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
201829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
201929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
20204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
2021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
20220f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
202329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2024df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
202595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
20260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
20274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
2028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
202929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
20304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
20314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (!doComposeSurfaces(hw, dirtyRegion)) return;
2036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
20384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2039da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2040da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2041da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
20459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
20489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
20509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
20519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
20529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
20539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
20549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
20559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
20569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
20579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
20589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
20609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
20619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2062a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
20639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2064c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
20659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
20663f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
20673f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
20683f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
20693f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
20703f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2071c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2072a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2073a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
20749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
20759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2076b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2078b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
20793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2080b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
20819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2082b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2083766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
20849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2085766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2086766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2087766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2088766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
20899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2090766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2091766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
20929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2093766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2094766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2095766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2096766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2097b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
209887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2099b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
21009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2101b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2102a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2103f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2105766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2106f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2107f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
21089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
21099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2110f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2111f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2112f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2113f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
21143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2115f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
21169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
21179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
21183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2119f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2120f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
212185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
21224b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
212385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
212485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
212585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
21264b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
21279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
21289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
21299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
213085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
21319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
21329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
21339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
21349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
21369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
21379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
213885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
21409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
21419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
21429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2143ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
21449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
21459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
21469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2147cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2148cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->clearWithOpenGL(displayDevice, clip);
2150cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
215185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
215285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
21549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
215585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2156a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2158da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2159cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
21609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
21619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2162a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
21639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
216485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
216585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
216685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
21679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
216885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
21699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
217085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
21719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
217285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
21734b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
21744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2175f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21769f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
21779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
21789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
21799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2180f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
21819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
21823f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
218655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
21873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
21883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2192ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
21936710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
219413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
21951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
21967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
21977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
21987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
21997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
22007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
22017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
22027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mCurrentState.layersSortedByZ.add(lbc);
22037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
22047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
22057d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
220696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2207ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
22084f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
22097d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
221096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
221196f0819f81293076e652792794a961543e6750d7Mathias Agopian
221292cd24e5f648175944deef5899258981807a9ca4Dan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
221396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
221492cd24e5f648175944deef5899258981807a9ca4Dan Stoza    sp<Layer> layer = weakLayer.promote();
221592cd24e5f648175944deef5899258981807a9ca4Dan Stoza    if (layer == nullptr) {
221692cd24e5f648175944deef5899258981807a9ca4Dan Stoza        // The layer has already been removed, carry on
221792cd24e5f648175944deef5899258981807a9ca4Dan Stoza        return NO_ERROR;
221892cd24e5f648175944deef5899258981807a9ca4Dan Stoza    }
221992cd24e5f648175944deef5899258981807a9ca4Dan Stoza
2220598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
2221598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (index >= 0) {
2222598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersPendingRemoval.push(layer);
2223598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersRemoved = true;
2224598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        setTransactionFlags(eTransactionNeeded);
2225598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        return NO_ERROR;
2226598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
2227598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    return status_t(index);
2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2230c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
2231dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2232dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2233dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
22343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
224199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
22478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
22488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
22498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
22508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
22517c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2252698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
225328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
22552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
22562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
22572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
22582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
22597c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
22602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
22612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
22627c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
22637c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
22647c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
22652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
22662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
22672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
22682d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
22692d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
22702d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2275b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2276b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2278698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2279698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2280d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2281d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2282d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2283d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2284d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2285d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2286d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2287d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2288097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2289d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2290d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2291d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2292d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2293d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2294d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2295d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2296d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2297698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2298386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
22992a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
23002a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
23012a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
23022a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
23032a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
23042a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
23052a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
230628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2307386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
230828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2309698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2310386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2311386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2312386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
23132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
23142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
23162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2317386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
23182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2319386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2320386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2321386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2322386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
23232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
23242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2325386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2326386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2327cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2331e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2332e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
23339a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
23349a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
23359a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
23369a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
23389a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
23393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2342097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2343e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2344e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2346e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2347e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2348e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2349e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2350e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2351e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2352e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
235300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2354e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2355e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2356e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2357e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2358e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2359e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2360e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2361e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2362e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2363e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2364e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2365e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2366e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
236747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
236847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
236947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
237047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
237147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
237247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
237347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
237447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
237547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
237647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2377e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2378e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2379e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2380e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2381e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2382e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2383e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2385e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
238613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2387e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2388e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
238999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
239099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2391e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
239299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2393e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
239482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2398e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
239947db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayer(s.z) && idx >= 0) {
2400e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2401e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2402e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
24139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2420e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2421e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2424231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2427e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2428e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
242999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2432acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2436e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
243947db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
2440e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2441e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2444e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2445e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2446e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
24477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
24487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            layer->deferTransactionUntil(s.handle, s.frameNumber);
24497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
24507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
24517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2452c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2453c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2454c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2455c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2456c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
24614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
24620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
24630ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
24644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
24654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
24686e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2469921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
24706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
24714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
24726e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
24738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
24744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
24754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
24764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
24774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
24783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
24793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
24804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
24814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
24824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
24843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
24854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
24864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
24874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
24884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
24894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
24904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
24957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
24977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
24987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    result = addClientLayer(client, *handle, *gbp, layer);
24997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
25007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
25017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
25027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
25037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
25044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
25084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
25094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
251292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
25188f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
25234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
25244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
25254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2526b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
25304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
25344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
25354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
25384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2539b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
25404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2541118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2542118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2543ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
25449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
25456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
25466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
25476710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
25486710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
25496710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
25506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
25516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
25529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
25539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
25549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
25559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
255613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25586710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
25596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
256092cd24e5f648175944deef5899258981807a9ca4Dan Stoza    return removeLayer(layer);
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) {
2621f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
26222c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2623c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2624c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2625c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2626948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2627c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2630b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
26312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
2632f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2633f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2634f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
2635f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
2636f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
2637f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
26382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2639f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
2640f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2641f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
2642f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
2643f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
2644f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2645c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2646948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2647948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2648cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2649cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2650cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2651c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
26522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
26532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
26552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
26562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2657b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
26612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2662db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2663db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
26642c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2665b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
26662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
26672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
26682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2669b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
26702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2671db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
26722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
26737306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
26749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
26752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2677db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
26782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2679db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2680b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2681b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2682b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
26832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2684db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2685b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2686b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2687b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2688b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
269299b49840d309727678b77403d6cc9f920111623fMathias Agopian
2693bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2694bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2695bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2696bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2697bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
269874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2699bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2701fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
27029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
27039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2704fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2705fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
27069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2707fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2708fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2709fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
27109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
27119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
271282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
271382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
271425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
271525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
271625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
271725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
271825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
271974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
272035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
272125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
272225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
272325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
272425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
272582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
272674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
272735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
272882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
272925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
273025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
273125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
273225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
273374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
273435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
273525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2736c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2737c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2738c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2739c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2740c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2741c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2742c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2743b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2744b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2745b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2746b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2747b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2748b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2749b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
275040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
275140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
275240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                    (args[index] == String16("--fences"))) {
275340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
275440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                mFenceTracker.dump(&result);
275540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
275640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
27581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
275982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
276074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
276182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
276248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
276382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
276482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
276548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
276682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
276782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
276882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
276982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
277048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2771c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2772c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
277325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
277425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
277525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
277625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
277713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
277874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
277925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
278025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
278125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
278282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
278374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
278482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
278582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
278682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
278782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
278882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
278982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
279048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
27919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
27929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
279386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
27944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
27954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2796d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
27974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
27984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
27994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
28004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
280113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
28024b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2803d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
28044b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
280582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
280682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
280782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2808ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
280925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2810c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
281125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
281225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
281325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
281425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
281525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
281625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
281725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
281825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
281925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
282025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
282113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
282225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2823d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
282425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
282525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
28264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2827d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
282825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
282925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
28306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
28316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
28326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
28336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
28346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
28356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
28366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
28376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
28386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
28396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
28406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
28416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
28426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
28434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
28444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
28454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
28464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
28474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
28484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
28494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
28514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
28524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
28544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
28554803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
28564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
28574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
28584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
28594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2860b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2861b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2862b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2863b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2864b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2865b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2866b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2867b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2868b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2869b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2870b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2871b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2872b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2873b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2874b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2875b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2876b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2877e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
2878e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
2879e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2880e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
2881e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
2882e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
2883e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
2884e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2885e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
2886e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
2887e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
2888e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
2889e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2890e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
2891e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
2892e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2893e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2894e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2895e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
2896e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
2897e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
2898e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
2899e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2900e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
2901e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
2902e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
2903e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
2904e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
2905e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
2906e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
2907e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2908e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
2909e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
2910e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
2911e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
2912e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
2913e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
2914e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
2915e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
2916e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
2917e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2918e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
2919e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
2920e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
2921e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
2922e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
2923e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
2924e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
2925e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2926e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
2927e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2928e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2929e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
293074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
293174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
293282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
29333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
29343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
29353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
29363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
29373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
29383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
29393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
29403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
29413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
294282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
294382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
294482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
294582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
294682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
294782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2948bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
294982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
29504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
29514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
29523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
29533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
29544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
29553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
29564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
29574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
29584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
29594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
29604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
29613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2962ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
29633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2964ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2965ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2966ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
29679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
29689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
296941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
297041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
297141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
297224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
297324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
29749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
29759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
297641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
297741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
2978b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
2979b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2980b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
2981b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2982b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
29854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
298682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
298782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
298882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
298982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
29903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
299186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
29923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
299382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
299413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
29953e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
299682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2997bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
299882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
29995f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
30005f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
30015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
30023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
300386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
30043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30055f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
30065f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
300774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
30085f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
30095f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
30105f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
301182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
301282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
30131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
30143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
301574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
30163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3018888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
30194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3020ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
30213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
30223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
30233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
30243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3026ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3027ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3028875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
30299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
30304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
30312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
30322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
303374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
303482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
303582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3036c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
303782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
303882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3039ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3040ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3041ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
304282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
304382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3044c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
30459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
30469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
30479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3048ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
304982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
305074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
305182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
305282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
305374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
305482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
305582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
305682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
305782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
305882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
305974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3060e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3061e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3062e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3063e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3064e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3065e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3066e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3067e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3068e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3069e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3070e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3071e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3072e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3073e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
3074e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        for (size_t l = 0; l < count; l++) {
3075e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            const sp<Layer>& layer(currentLayers[l]);
3076e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
3077e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3078e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3079e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
308082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
308182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
308282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
308382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
30843e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
308574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
30863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
30889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
30899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
309074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
309182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
309282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
309382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
309482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
309582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
309682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
309913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
310048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3101db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
310248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
310348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
310448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
310548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
310648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
310748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
310848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
310948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
311048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
311148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
311248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
311348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
311448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3115cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3116cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
311763f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
311863f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
311963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
312063f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
312163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
312263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
312363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
312463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
312563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
312624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
312763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
312863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
312963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
313063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
313163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
313263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
313363f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
313463f165fd6b86d04be94d4023e845e98560504a96Keun young Park
3135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
3136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3140041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3141698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
3142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3143d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3144d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
31452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3146c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3151a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
31523bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
315399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
3154e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
3155375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3156375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
31581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
31591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
31601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
31611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
31621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
31631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
31641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
31651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
316699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
316799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
3168e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
31691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
31701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
31711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
31721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
31751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3178b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
317999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3180375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3181375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3182375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3184375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
318901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
319035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
319553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
319653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
319953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3200cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3201cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3202cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3203e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3207cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
32094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
32104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
32114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
32124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
321353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
321453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
321553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
321653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
321753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
321853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3219a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3220a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3221a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3222a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3223a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3224a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
322601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3229b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
323012839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
32344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
32354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3236ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3237ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3238ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3239ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3240ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3241ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
32429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
32439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
32449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
32469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
32479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
32499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
32509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
32519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
32529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
32539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3254ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3255ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
32569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3257ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
32589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3259ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3260ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3261ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
32629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
32639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
32649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
32659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
32669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
32679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
32689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
32699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
32709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3271794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
32729f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
32739f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
32749f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
32759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
32769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
32779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
32789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
32799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
32809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
32819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3283f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3284f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3285f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3286645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3287645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3288f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3289f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3290ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3291ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3292ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3293ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3294ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3295db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3296db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3297db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3298db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3299db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3300db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3301db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3302db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3303db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3304db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
33053cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza            case 1021: { // Disable HWC virtual displays
33063cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                n = data.readInt32();
33073cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                mUseHwcVirtualDisplays = !n;
33083cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza                return NO_ERROR;
33093cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza            }
3310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
331553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
331687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
331799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
331853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
331953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
332059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
33212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
33222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
332359119e658a12279e8fff508f8773843de2d90917Mathias Agopian
33242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
33252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
33262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3327b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3328b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3329b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3330b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
33312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
33322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3333b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3334b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3335b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3336b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3337b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3338b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3339b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3340b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3341b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3342b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3343b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3344b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3345b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3346b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
33472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
33482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
33492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
33502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
33512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3352b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
33532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
33542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
33552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
33562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
33582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
33592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
33602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
33612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3363b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3364b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3365b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
33662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
33672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3368c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
33692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
33702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
33712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
33722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3373b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3374b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3375b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3376b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
33772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
33782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
33792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3380b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3381b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3382b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
33832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
33842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
33852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3386c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
33872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
33882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
33892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3390b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
33912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
33922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
33932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3394b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3395b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3396b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3397b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3398097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
33992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3400b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
34012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
34022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
34032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
34042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3406b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3407b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3408b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
340953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3410b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
341153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
341253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
341353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
341453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3415b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3416b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3417b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
34182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
34192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
34202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
34212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
34222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
34232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
34242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3425b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
34262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3427aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
34282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3429b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3430b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3431b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
34322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
34332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
34342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
34352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
34382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3439c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3440c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3441c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
34422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
34442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
34452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
34472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
34482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
34495ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
34505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
34515ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3452b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
34535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3454c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3455c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3456c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3457c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3458c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3459c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3460c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3461c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3462c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3463c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3464c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3465c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3466c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3467c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3468c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3469c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3470c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3471c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3472c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3473c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3474c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
34752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
34762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
34772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
34782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3479c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
34802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
34812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3482c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3483c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
34842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3485b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
34862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
34872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
34882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
34892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3490c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3491c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3492b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3493b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3494b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
34952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3496c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
34972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3498c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3499b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3500b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
35012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
35022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
35032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
35042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
35052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
35062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
35072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
35082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3509c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3510c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3511b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3512097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
35132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
35142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
35152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
35162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
35182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
35232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
35242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
35252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3526c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3527b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
35282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
35302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
35312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
35322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
35332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3534118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3535118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3536180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3537180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3538180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3539c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3540180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3541c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3542180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3543180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
35443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3545180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3546180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
354789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
354889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
354989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
35500e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3551180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3552c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3553c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3554c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3555c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3556c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3557c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3558c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3559c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3560c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3561c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3562c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3563be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3564be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3565c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3566c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3567c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3568c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3569be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3570be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3571c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3572c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3573180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
35743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3575180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3576180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3577c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3578c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
35793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3580180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3581180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
35823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3583180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3584180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3585180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3586180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3587180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
35881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3589180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3590180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3591180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3592180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3593c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3594180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3595180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3596180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3597180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3598180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3599180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3600931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3601180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3602180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3603180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3607c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3608c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3609b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
3610b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
361174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3612fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3613fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3614180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
36153502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
36163502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
36173502416204d9dbd905012ee586d8bd145323809fDan Stoza
36183502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
36193502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
36203502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3621180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3622180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3623180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3624180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3625180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3626180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3627180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3628180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3629180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3630180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3631b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
3632b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const LayerVector& layers(mDrawingState.layersSortedByZ);
3633b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const size_t count = layers.size();
3634b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    for (size_t i = 0 ; i < count ; ++i) {
3635b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const sp<Layer>& layer(layers[i]);
3636b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
3637b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
3638b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                state.z <= maxLayerZ && layer->isVisible() &&
3639b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                layer->isSecure()) {
3640b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            secureLayerIsVisible = true;
3641b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
3642b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3643b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
3644b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
3645b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
3646b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
3647b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3648b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
36490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
36500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
365183cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
3652605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
3653605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
3654605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
3655605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
3656605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
3657605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
3658605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
3659605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
36600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
366174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
36625a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
36635a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
36643ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
36653ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
36662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
36680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
36694ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
36700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
36710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
36722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
36740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
36750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
36760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
36770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
36780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
36790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3680866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
36810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
36820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
36830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
36840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
36850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
36863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
36873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
36883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
36893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
36900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
36910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
36920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
36930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3694c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3695c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3696c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3697d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3698866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3699866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3700866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3701866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3702866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3703866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
37049707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
37059707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3706866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3707866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3708866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
37092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3710866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3711866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3712866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3713866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3714866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3715866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
37162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3717866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3718866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3719866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3720866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3721866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3722866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3723866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3724866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3725866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3726866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3727866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3728866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3729866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3730866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
37312d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3732866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
37332d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
37342d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3735d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3736d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3737d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3738d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3739d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3740d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3741d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3742d555684cb36dfb959694db76962e570184f98838Mathias Agopian
37430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
37440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
37450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
3746f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
3747f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
37480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
37490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
37500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
37510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
37520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
375374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3754f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
3755f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
3756f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
3757f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
375874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
37590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
37600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
376174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
37620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
376374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
376474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
376574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
376674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
376774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3768d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3769d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3770fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3771d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3772d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3773d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3774fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3775fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3776fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3777fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3778fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3779fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3780fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3781fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3782fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3783fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3784fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3785fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3786fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3787fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
37889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
3789fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3790fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3791fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3792fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3793fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3794fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3795fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
3796ce796e78a57018f186b062199c75d94545318acaPablo Ceballosbool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
3797ce796e78a57018f186b062199c75d94545318acaPablo Ceballos        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
3798ce796e78a57018f186b062199c75d94545318acaPablo Ceballos    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
3799ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
3800ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
38011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
38021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3803921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3804921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3805921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3806921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
380713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3808921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3809921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3810921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3811921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3813be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
381413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
381513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3816be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
38171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
38181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3819be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3820be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3821be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
38221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
38231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3824be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3825be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3826be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3827be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3828921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3829921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3830921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3831921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
38323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
383353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    : type(DisplayDevice::DISPLAY_ID_INVALID),
383453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      layerStack(DisplayDevice::NO_LAYER_STACK),
383553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      orientation(0),
383653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      width(0),
383753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      height(0),
383853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      isSecure(false) {
383953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos}
384053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos
384153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo CeballosSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(
384253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDevice::DisplayType type, bool isSecure)
384353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    : type(type),
384453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      layerStack(DisplayDevice::NO_LAYER_STACK),
384553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      orientation(0),
384653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      width(0),
384753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      height(0),
384853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos      isSecure(isSecure) {
3849da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3850da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3851b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
38527303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3853b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
385496f0819f81293076e652792794a961543e6750d7Mathias Agopian
3855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
38563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
38593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
38603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
38613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
38633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
38643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3865