SurfaceFlinger.cpp revision 2047fae0cfed99c425dc7333f31d309e5b8ee1ba
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>
24c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju#include <mutex>
2563f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
2686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
27b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
29921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
327823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
4067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
41c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
46e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
47392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
53cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
570a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h>
581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
61ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
68faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
69d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
70d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
76a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
82ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
83875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
91fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
92ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
93ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12799b49840d309727678b77403d6cc9f920111623fMathias Agopian
12899b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12999b49840d309727678b77403d6cc9f920111623fMathias Agopian
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1314f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
137875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1424b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1448afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
146a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
151ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
152ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
153468051e20be19130572231266db306396a56402bIrvel        mInterceptor(),
1544a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
155faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
156948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
160b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
161b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mLastSwapTime(0)
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
163a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1678afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
168b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
16950210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
170b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1738afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1758afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
17763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
17863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
17963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
18063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1818afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
182c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
183c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
184c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
185c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
186c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
187c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
1888cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
1898cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    property_get("debug.sf.disable_hwc_vds", value, "0");
1908cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    mUseHwcVirtualDisplays = !atoi(value);
1918cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
19263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard
19363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    property_get("ro.sf.disable_triple_buffer", value, "0");
19463a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    mLayerTripleBufferingDisabled = !atoi(value);
19563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
205a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
206a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
207a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
21299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
21399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
21413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
21513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
21699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
21799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
21999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
22099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2217e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
22496f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
22596f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
22696f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
22796f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
232dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
233dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
244c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
25253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2538dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
255ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
273ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2766c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
278692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
2799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
280692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
281692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
282692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
283692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
28453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
285692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
286ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
288692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2909e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
291e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
294692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
3009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
3019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
307a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3083330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
318a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
319a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3210a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3220a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3230a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3240a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
328921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
338921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
339921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
341921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
342921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3455167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3464a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3474a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3504a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3514a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
352db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
353db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
354db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
355db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
356db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
357db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
362db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3644a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3705167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3785167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
379faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
380db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4154a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
417db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
418db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
419db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
421db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
422db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
426faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
427db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
429a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4300a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4325167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
436faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4414a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4424a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
443faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
444faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4450a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4465167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4475167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
449faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
450db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
451db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
455db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
457faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
459c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
460c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
461c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
462c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
463c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
464c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
465c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
466c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
467c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
468c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
469c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
470c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
471c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
472c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
473c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
474c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
475c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
476c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
477c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
478c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
479c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
480c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
481c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
482c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
483faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
484a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
485a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
493692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
497ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
500ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
502a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
503acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
50441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
50535520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
50641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
50741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
50841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
50941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
514f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc = new HWComposer(this);
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
520b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
522875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
523875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
524875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
525a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
526da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
527da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
528da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
531a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
532a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
533d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
534d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
535d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
53692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
53792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5388630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
53913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
54013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
54113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
5424e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
5434e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
544a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
545a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
5483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
550a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
551a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
552a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
553a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
554a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
555a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
556875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
557875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
558a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
559a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
560875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
561875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
562a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
563a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
565d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
566582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5672adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
568134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
569097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
571134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
572134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
573069b365163470d2736eb6f591c354d208b5da23bBrian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps(
5743890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        std::vector<FrameEvent>* outSupported) const {
575069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    *outSupported = {
5763890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::REQUESTED_PRESENT,
5773890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::ACQUIRE,
578f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::LATCH,
5793890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::FIRST_REFRESH_START,
580f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::LAST_REFRESH_START,
5813890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::GL_COMPOSITION_DONE,
5823d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        getHwComposer().presentFenceRepresentsStartOfScanout() ?
5833890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson                FrameEvent::DISPLAY_PRESENT : FrameEvent::DISPLAY_RETIRE,
584f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::DEQUEUE_READY,
5853890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::RELEASE,
586069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    };
587069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    return NO_ERROR;
588069b365163470d2736eb6f591c354d208b5da23bBrian Anderson}
589069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
5907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
59223e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5967aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5977aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5987aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
599692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6009e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
601692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6021604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6031604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6041604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6051604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6061604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6071604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6081604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
609c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
6168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
6178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
6188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
6198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
6208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
6218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
6228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
6238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
6248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
6258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
6268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
6271604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
6407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
6417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
6467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
6477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
6647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
66791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
66991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
67091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
67191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
67291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
67391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
67491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
67591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
67691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
67791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
67891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
67991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
68091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
68728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
6888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6898b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
692dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
69389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
69467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
69567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
69667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
69767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
69867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
69967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
70067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
70167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
70267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
70367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
70467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
70567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
7079f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    if (display == NULL) {
7089f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        ALOGE("%s : display is NULL", __func__);
7099f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        return BAD_VALUE;
7109f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    }
71124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
71224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
71324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
71424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
71524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
7167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
717dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
7186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
7226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
7356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
7366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
7376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
7396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
7406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
7416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
7426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
7436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
7446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
7456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
7466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
7476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
7487306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
7497306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
750784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
7519ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7527306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
75328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
7547306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7587306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7636c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
770888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
771c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
81728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
81828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
81928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
82028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
82128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
82228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
82328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
82428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
82528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
82628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
82728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
82828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
82928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
83028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
85528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
85628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
85728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
85828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
85928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
86028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
86128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
867c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
868d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
869d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
870d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
871d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
872d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
873d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
874d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
875d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
876d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
877d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
878d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
879d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
880c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
881c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
882c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
883c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
884c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
885c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
886c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
887c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
888c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
889c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
890c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
891c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
892c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
893c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
894c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
895c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
896c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
897c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
898c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
899c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
900c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
901c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
902c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
903c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
904c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
905c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
906c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
907c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
908c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
909c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
910c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
911ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
912c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
913c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
914c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
915c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
916c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
917c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
918c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
919c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
920c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
921c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
922c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
923c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
924c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
925c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
926c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
927c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
928c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
929c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
930c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
931c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
932c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
933c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
934c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
935d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
936d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
937d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
9388aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
939bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
940bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
94299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
94499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
94599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
94899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
95299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
95399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
95699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
95799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
960c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
96199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
96299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
96399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
96499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
965c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
96699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
96799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
96899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
96999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
97099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
97199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9734f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
9744f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
9754f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
9764f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
97799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
979faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
980faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
981948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
982faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
983d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
984d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
985faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
98643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
987faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
988faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
989948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
990faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
991faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
992948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
993948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
994948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
9950a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
9960a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
997948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
998948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
999948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
10009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
10019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
1002faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
1005faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1006faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1008d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1009d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1010faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
1011faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1012faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1014948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1015faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1016faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1017d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1018d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1019faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1020faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1021faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1022948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1023948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1024948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1025faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1026faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
10274a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
10284a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
10294a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
10300a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
10314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
10324a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
10334a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
10349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
1035d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1036faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1037d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1038d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1039d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1040d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1041faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1042148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1043d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1044d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1045d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1046d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1047d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1048d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1049148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1050148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
10589e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer,
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                new GraphicBufferAlloc());
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
10769e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1077692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
10799e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1080692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1081692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
10829e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
10839e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
10849e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10859e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
10863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
10878630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10888630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1090faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
10938630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10948630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
10961c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
109799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
10986b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
10995018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
11005018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
11015018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence->getSignalTime() == INT64_MAX;
11025018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1103c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
11045018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
11055018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
11065018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
11075018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
11105878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
11116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
11125878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
11135878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
11145878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
11156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
11166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
11176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
11206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
11216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11266b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1127c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard    uint32_t transactionFlags = peekTransactionFlags();
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
112987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
11306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
11314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
11334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11356b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1136cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
11376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
11393a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
11404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
114214cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
114340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
114405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
1145d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    preComposition(refreshStartTime);
114605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
114705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
114805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
114905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
1150d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    postComposition();
115105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
115211d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
1153bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1154bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1155bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1156bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1157bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1158bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1159bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
116014cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
11619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1162cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1163cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1164cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1165cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1166cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1167cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1169cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1170cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1171cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1172cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1174cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1175cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1176cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1177cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1178cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1179cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1180cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1181cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
11823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
11833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
11843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1185da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1187cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1188cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1189cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1190cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1191cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1192cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1193cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1194cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1195bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
11969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
11977bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
11987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
11997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
12007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
12017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
12027bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
12039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
12049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1205bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1207cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1208d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
1209cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
12129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
12142047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
12152047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        if (layer->onPreComposition(refreshStartTime)) {
1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1217cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
12182047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
12192047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
1220cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1221cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1222cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1223cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1225d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::postComposition()
1226cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
12299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
12303546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    // Release any buffers which were replaced this frame
1231f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson    nsecs_t dequeueReadyTime = systemTime();
12323546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    for (auto& layer : mLayersWithQueuedFrames) {
1233f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson        layer->releasePendingBuffer(dequeueReadyTime);
12343546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    }
12353546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson
1236d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
12373d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12383d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
12393d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
12403d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime =
12413d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
12423d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
12433d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
12443d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
12453d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
12463d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mGlCompositionDoneTimeline.updateSignalTimes();
12473d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12483d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    sp<Fence> displayFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
12493d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    auto displayFenceTime = std::make_shared<FenceTime>(displayFence);
12503d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.push(displayFenceTime);
12513d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.updateSignalTimes();
12523d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12533d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    const std::shared_ptr<FenceTime>* presentFenceTime = &FenceTime::NO_FENCE;
12543d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    const std::shared_ptr<FenceTime>* retireFenceTime = &FenceTime::NO_FENCE;
12553d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->presentFenceRepresentsStartOfScanout()) {
12563d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        presentFenceTime = &displayFenceTime;
12573d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
12583d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        retireFenceTime = &displayFenceTime;
12593d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
12602047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
12612047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
12622047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                *presentFenceTime, *retireFenceTime);
1263e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
12642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            recordBufferingStats(layer->getName().string(),
12652047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    layer->getOccupancyHistory(false));
1266e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
12672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
12684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
12693d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (displayFence->isValid()) {
12703d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        if (mPrimaryDispSync.addPresentFence(displayFence)) {
1271faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1272faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1273948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1274faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1275faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1276faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
12775167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
12782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1279faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1280faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1281faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1282faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
12834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
12844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
12854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
12863d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        if (displayFenceTime->isValid()) {
12873d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson            mAnimFrameTracker.setActualPresentFence(
12883d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                    std::move(displayFenceTime));
12894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
12904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
12914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
12929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
12939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
12944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
12954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
12964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
12974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1298b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1299b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1300b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1301b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1302b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1303b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1304b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1305b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1306b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1307b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1308b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1309b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1310b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1311b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1312b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1313b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1314b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1315b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1316b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1317b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1318cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1319cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1320cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
13219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1324cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
132552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1326cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
132787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
132887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1329ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1331ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1332ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Vector<sp<Layer>> layersSortedByZ;
13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Transform& tr(displayDevice->getTransform());
13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect bounds(displayDevice->getBounds());
13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (displayDevice->isDisplayOn()) {
13382047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                computeVisibleRegions(
13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getLayerStack(), dirtyRegion,
13409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        opaqueRegion);
13417e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
13422047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mDrawingState.traverseInZOrder([&](Layer* layer) {
13431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
13449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (s.layerStack == displayDevice->getLayerStack()) {
1345a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1346a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1347a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1348a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1349ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
13509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // Clear out the HWC layer if this layer was
13529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // previously visible, but no longer is
13539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
13549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    nullptr);
1355ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
135687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
13572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                });
13583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
13599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
13609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.set(bounds);
13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.subtractSelf(
13629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    tr.transform(opaqueRegion));
13639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->dirtyRegion.orSelf(dirtyRegion);
13643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
13653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1366cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
13673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1368cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
13699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
13719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1372028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1373b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1374b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1375b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1376b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1377b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1378b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1379b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1380b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1381b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1382b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1383b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1384b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1385b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1386b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1387b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1388b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1389b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1390b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1391b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1392b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1393b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
13947143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1395b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1396b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1397b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1398b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1399028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1400028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
14019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
14039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool foundLayerWithoutHwc = false;
1411ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                for (size_t i = 0; i < currentLayers.size(); i++) {
1412ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    auto const& layer = currentLayers[i];
14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
14149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
14189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            foundLayerWithoutHwc = true;
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1421a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1422a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1423a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1424ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    layer->setGeometry(displayDevice, i);
14259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
14269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
142703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
142803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
142903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
143003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
14319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
143203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
14339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
14359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
14379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
14399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
14429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
14449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
14459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
14469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
14479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
14489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
145038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
145152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
14529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
14539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
14549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14567bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
14577bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14597bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14607bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
14617bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
14629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
14639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
14649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1465cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
146652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1467cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1468cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
14699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
14709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
147152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
147292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1475cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1476cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
147702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
147802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
147902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
148002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1481cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1482cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1483cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
148487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
14854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
148652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1491841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
14929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1493b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1496c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
14979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
14997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
15007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
15017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
15029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
15039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
1504a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard            mHwc->presentAndGetReleaseFences(hwcId);
15059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
15062dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1507b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
15089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
15099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
15109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
15119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
15129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
15139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
15149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
151552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
15169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
15179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
15189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
15199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1520ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1521e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1522e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1523a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1524a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
15256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
15266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
15276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
15286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
15296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1534841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1535841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
15367cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
15377cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
15387cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
15397cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
15407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
15417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1542ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1543ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1544ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1545ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1546ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1547ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1548ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1549ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1550ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1551ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
155387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1554ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1555ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1556ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1557ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
15593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
15623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
15633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
15662047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([](Layer* layer) {
15672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        layer->notifyAvailableFrames();
15682047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
15697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
15762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
15782047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (!trFlags) return;
1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
15832047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
15873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
159192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
159292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
159392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
159692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
159892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
159993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
160092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
160192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
160292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
160392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
160492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
160592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1607e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
160892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
16093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
161027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
161127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
161227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
161302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1614875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
161502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
161602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
161702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
16189e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
16197adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
162002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
162192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
162292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
162392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
162492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
162592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1626e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
16273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1628097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1629097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
16301474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1631e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
163293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
163393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
163493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
163502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
163602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
163702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
163893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
163993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
164093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
164193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
164293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
164392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
164493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1645db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
164693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
164793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
164893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
164993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
165000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
165100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
165200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
165300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
165400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
16554fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
165693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
165747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
165847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
165947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
166092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
166192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
166292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
166392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
166492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
166592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
166692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1667e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1668e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1669cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
167099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1671db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1672b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1673b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
167470982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
167570982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                            new GraphicBufferAlloc());
1676db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
16779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
167899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
167902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
168002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
168102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
168299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1683db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
16848cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            if (mUseHwcVirtualDisplays) {
16858cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int width = 0;
16868cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int status = state.surface->query(
16878cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
16888cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16898cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query width (%d)", status);
16908cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int height = 0;
16918cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
16928cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
16938cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16948cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query height (%d)", status);
16958cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int intFormat = 0;
16968cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
16978cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
16988cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16998cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query format (%d)", status);
17008cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                auto format = static_cast<android_pixel_format_t>(
17018cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        intFormat);
17028cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
17038cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
17048cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        &hwcId);
17058cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            }
17069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
17075cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
17085cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
17099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
17109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
17119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
17129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
1713db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1714db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
171547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
171699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
171799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1718cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1719cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1720cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1721cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
17229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
17239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            hwcId = DisplayDevice::DISPLAY_EXTERNAL;
17249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            dispSurface = new FramebufferSurface(*mHwc,
17259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    DisplayDevice::DISPLAY_EXTERNAL,
17269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    bqConsumer);
17279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            producer = bqProducer;
17289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
17299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            ALOGE("Attempted to add non-external non-virtual"
17309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    " display");
17319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        }
1732cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1733cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1734cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
173599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1736cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                state.type, hwcId, state.isSecure, display,
17389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                dispSurface, producer,
173905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1740cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1741cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
17424fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
17438dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1744cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
17459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
17467adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
17471c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
174893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
174992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
175092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
17558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
17568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
17578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
17588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
17608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
17618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
17638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
17648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
17658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
17678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
17688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
17708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
17718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
17728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
17738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
17758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
17762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool first = true;
17772047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
17788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
17798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
17808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
17811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
17822047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (first || currentlayerStack != layerStack) {
17838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
17848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
17858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
17868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
17878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
17888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
17898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
17908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
17918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
17928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
17938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
179491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
17958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
17968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
17978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
17988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
17998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
180091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
180191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
180291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
180391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
180491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
180591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
180691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
180791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
18088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
180991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
18102047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
18112047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            first = false;
18122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
18138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
18148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
18158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
18163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
18173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
18183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
18191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
18201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
18213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
18223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
18233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
18243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
18253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
18263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
18273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
18283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
18293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
18302047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
18313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
18323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
18333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
18343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
18353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
18361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
18373dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                Region visibleReg = s.active.transform.transform(
18381501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
18391501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
18400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
18412047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
184503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
184603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
184703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
184803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
184903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
185003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
18519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
18529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
18539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
185403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
185503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
18569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
18579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
18589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
185903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
186003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
18624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
18634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
18644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
1865598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
18664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
18674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
1868e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
1869e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    mLayersPendingRemoval[i]->getOccupancyHistory(true));
18704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
18714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
18724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
18734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
18744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
18754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
18764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
18774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
18784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
18794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
18802d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
18812d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
18824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18852047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
188687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1888841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
18899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
1890841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
189587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18972047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
18991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
190287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
19032047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            return;
190487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1909ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1910ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1911ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1915ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1917ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1919ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1921ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1923ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1924a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1925a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1926a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1927a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1928a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1929a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1930a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1931a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1932a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1933a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1936da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
19374125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
19383dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            Rect bounds(s.active.transform.transform(layer->computeBounds()));
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1940ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1941ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1942ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
19433dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                    const Transform tr(s.active.transform);
194422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
194522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
194622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
19474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
194822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
194922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
195022f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
19514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1952ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
19553dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                const int32_t layerOrientation = s.active.transform.getOrientation();
19569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
1957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1959ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
19784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1981a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1983ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1984ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1985ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1986ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1987ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1988ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1989ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1990ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1991ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1992a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1993ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
19944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
19954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1996ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1997ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
2000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
200287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2004ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
2005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
20068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2007a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
2008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
2009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
2010a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
2011a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
20122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
2013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
2015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
201887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
201992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
20204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
20214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
20224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
202392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
202492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
202587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
202687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
20276b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
20309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2031d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    nsecs_t latchTime = systemTime();
203299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
20346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
203551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
203651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
203751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
203851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
203951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
204051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
204151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
204251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
204351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
204451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
20452047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
20466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
20476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
20486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
20492047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mLayersWithQueuedFrames.push_back(layer);
2050ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2051ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
20526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2053ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2054ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
20556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
20562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
20572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
20589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
2059d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
2060ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
20611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
206287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
20634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
20644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
20653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
20666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
20686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
20696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
20709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
20716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
20726b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
20736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
20759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
2076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2078ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2079ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
20809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2081ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2082ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
208399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2084830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition(
2085830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        const sp<const DisplayDevice>& displayDevice,
208687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20887143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
20897143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
20907143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
20917143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
2092830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
20937143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
20949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
20957143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
20967143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
20977143316af216fa92c31a60d4407b707637382da1Dan Stoza
20989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
20999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
210087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
210187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2102b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
2103830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2105830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    uint32_t flags = displayDevice->getFlags();
21060f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
210729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
210829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
210929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
2110830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        dirtyRegion.set(displayDevice->swapRegion.bounds());
2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
21120f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
211329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2114df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
211595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
21160f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
2117830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->swapRegion.bounds());
2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
211929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
2120830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->bounds());
2121830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            displayDevice->swapRegion = dirtyRegion;
2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2125830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
2126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
2128830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2129da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2130da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2131830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapBuffers(getHwComposer());
2132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
21389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
21409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
21429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
21439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
21449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
21459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
21469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
21479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
21489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
21509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
21519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2152a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2154c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
21559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
21563f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
21573f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
21583f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
21593f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
21603f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2161c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2162a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2163a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
21649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
21659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2166b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2167b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2168b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
21693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2170b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
21719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2172b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2173766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
21749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2175766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2176766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2177766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2178766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
21799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2180766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2181766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
21829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2183766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2184766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2185766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2186766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2187b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
218887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2189b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
21909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2191b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2192a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2193f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2195766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2196f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2197f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
21989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
21999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2200f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2201f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2202f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2203f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
22043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2205f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
22069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
22083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2209f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2210f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
221185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
22124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
221385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
221485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
221585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
22164b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
22179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
22189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
22199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
222085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
22219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
22229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
22239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
22249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
22259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
22269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
22279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
222885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
22309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
22319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
22329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2233ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
22349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
22359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
22369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2237cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2238cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
22391748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard                            layer->clearWithOpenGL(displayDevice);
2240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
224185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
224285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
22439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
22449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
224585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2246a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
22479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2248da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2249cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
22509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
22519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2252a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
22539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
225485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
225585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
225685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
22579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
225885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
22599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
226085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
226285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
22634b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
22644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2265f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
22669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
22679f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
22689f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
22699f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2270f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
22719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
22723f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2275830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
2276830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    const int32_t height = displayDevice->getHeight();
22773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
22783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22817d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2282ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
22836710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
228413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
22851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
22867d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
22877d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
22887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
22897d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
22907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
22917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
22927d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mCurrentState.layersSortedByZ.add(lbc);
22937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
22947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
22957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
229696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2297ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
22984f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
22997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
230096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
230196f0819f81293076e652792794a961543e6750d7Mathias Agopian
230222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
230396f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
230422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    sp<Layer> layer = weakLayer.promote();
230522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    if (layer == nullptr) {
230622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        // The layer has already been removed, carry on
230722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        return NO_ERROR;
230822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    }
230922851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza
2310598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
2311598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (index >= 0) {
2312598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersPendingRemoval.push(layer);
2313598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersRemoved = true;
2314598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        setTransactionFlags(eTransactionNeeded);
2315598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        return NO_ERROR;
2316598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
2317598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    return status_t(index);
2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2320c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() {
2321dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2322dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2323dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
23243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
233199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23368b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
23378b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
23388b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
23398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
23408b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
23417c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2342698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
234328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2344e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
23452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
23462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
23472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
23482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
23497c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
23502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
23512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
23527c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
23537c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
23547c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
23552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
23562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
23572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
23582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
23602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2361e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2362e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2363e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2364e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2365b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2366b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2367e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2370d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2371d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2372d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2373d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2374d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2375d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2376d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2377d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2378097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2379d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2380d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2381d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2382d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2383d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2384d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2385d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2386d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2387698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
23892a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
23902a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
23912a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
23922a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
23932a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
23942a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
23952a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
239628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2397ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2398ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2399ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2400468051e20be19130572231266db306396a56402bIrvel
2401386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
240228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2403698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2404386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2405386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2406386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
24072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
24082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
24092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
24102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2411386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
24122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2413386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2414386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2415386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2416386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
24172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
24182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2419386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2420386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2421cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
24279a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
24289a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
24299a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
24309a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
24329a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
24333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2434e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2436097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2439e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2440e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2441e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2444e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2445e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2446e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
244700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2448e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2449e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
246147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
246247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
246347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
246447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
246547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
246647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
246747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
246847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
246947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
247047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
248013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2481e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2482e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
248399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
248499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2485e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
248699e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
248882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
249347db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayer(s.z) && idx >= 0) {
2494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
25079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2518231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
252399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2526acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2527acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2528acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2529acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
253347db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
2534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
25417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
25427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            layer->deferTransactionUntil(s.handle, s.frameNumber);
25437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
25447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
25457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2546c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2547c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2548c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2549c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2550c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
25560ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
25570ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
25584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
25594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25616e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2562921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
25636e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
25644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
25656e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
25668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
25674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
25684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
25704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25713165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
25723165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
25734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
25744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
25754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
25773165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
25784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
25794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
25804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
25814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
25824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
25834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25877d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
25887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
25917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    result = addClientLayer(client, *handle, *gbp, layer);
25927d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
25937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
25947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
2595ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
25967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
25977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
25984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
26024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
26034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
260692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
26128f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
26174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
26184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
26194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2620b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
26224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
26234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
26244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
26284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
26294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
26324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2633b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
26344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2635118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2636118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2637ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
26389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
26396710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
26406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
26416710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
26426710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
2643ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
26446710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
26456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
26466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
26479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
26489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
26499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
26509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
265113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
26546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
265522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    return removeLayer(layer);
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2658b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2659b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
266013a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
266101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
266213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
266313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
266413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
266501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
266601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2667692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
266801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
266913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
26704c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
26714c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
267247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
267347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
267413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
267513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
26776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
26789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
26799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
26806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
268113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
268213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
268313a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
268413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
268513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
268613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
2687c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
268813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
268913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
269013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
269113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
269213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
269313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
269413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
269513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
269613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
26972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
26982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
26992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
27002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
27012c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
27022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
270313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
27042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
27052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2706c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2707c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2708c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
27092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
27102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
27112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
27122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
27132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2714c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2715ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
2716ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
2717ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
2718ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
2719ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
2720ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
2721ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2722ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
2723ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
2724ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
27252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
2726f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
27272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2728c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2729c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2730c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2731948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2732c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2735b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
27362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
2737f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2738f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2739f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
2740f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
2741f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
2742f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
27432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2744f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
2745f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2746f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
2747f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
2748f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
2749f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2750c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2752948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2753cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2754cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2755cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2756c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
27572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
27582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
27592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
27602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
27612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2762b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2767db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2768db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
27692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2770b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
27712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
27722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
27732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2774b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
27752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2776db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
27772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
27787306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
27799e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
27802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
27812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2782db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
27832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2784db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2786b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2787b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
27882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2789db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2790b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2791b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2792b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2793b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
279799b49840d309727678b77403d6cc9f920111623fMathias Agopian
2798bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2799bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2800bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2801bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2802bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
280374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2804bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2806fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
28079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
28089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2809fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2810fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
28119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2812fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2813fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2814fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
28159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
28169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
281782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
281882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
281925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
282025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
282125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
282225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
282325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
282474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
282535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
282625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
282725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
282825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
282925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
283082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
283174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
283235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
283382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
283425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
283525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
283625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
283725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
283874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
283935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
284025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2841c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2842c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2843c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2844c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2845c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2846c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2847c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2848b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2849b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2850b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2851b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2852b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2853b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2854b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
285540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
285640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
2857d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    (args[index] == String16("--frame-events"))) {
285840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
2859d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                dumpFrameEventsLocked(result);
286040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
286140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
2862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
28631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
286482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
286574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
286682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
286748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
286882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
286982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
287048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
287182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
287282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
287382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
287482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
287548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2876c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2877c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
287825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
28792047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
288074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
28812047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
288225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
288325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
288482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
288574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
288682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
288782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
288882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
288982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
289082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
289182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
289248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
28939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
28949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
289586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
28964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
28974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2898d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
28994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
29002047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
29014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2902d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
29034b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
29042047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
290582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
290682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2907ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
290825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2909c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
291025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
291125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
291225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
291325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
291425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
291525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
291625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
29172047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
291825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2919d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
292025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
29212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
29224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2923d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
292425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
292525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
29266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
29276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
29286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
29292047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
29306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
29312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
29326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
29336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
29346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
29356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
293663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const
29374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
293863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" [sf");
29394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
294063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" HAS_CONTEXT_PRIORITY");
29414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
29424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
294363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" NEVER_DEFAULT_TO_ASYNC_MODE");
29444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
294563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    if (isLayerTripleBufferingDisabled())
294663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard        result.append(" DISABLE_TRIPLE_BUFFERING");
294763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append("]");
29484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
29494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2950b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2951b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2952b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2953b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2954b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2955b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2956b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2957b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2958b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2959b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2960b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2961b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2962b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2963b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2964b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2965b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2966b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2967e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
2968e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
2969e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
2971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
2972e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
2973e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
2974e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2975e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
2976e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
2977e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
2978e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
2979e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2980e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
2981e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
2982e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2985d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
2986d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("Layer frame timestamps:\n");
2987d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
2988d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
2989d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const size_t count = currentLayers.size();
2990d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    for (size_t i=0 ; i<count ; i++) {
2991d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        currentLayers[i]->dumpFrameEvents(result);
2992d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
2993d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
2994d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
2995e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
2996e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
2997e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
2998e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
2999e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
3001e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
3002e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
3003e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
3004e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
3005e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
3006e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
3007e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3008e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
3009e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
3010e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
3011e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
3012e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
3013e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
3014e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
3015e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
3016e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3017e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3018e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3019e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3020e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3021e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3022e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3023e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3024e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3025e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3026e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3027e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3028e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3029e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
303074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
303174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
303282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
30333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
30343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
30353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
30363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
30373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
30383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
30393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
30413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
304282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
304382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
304482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
304582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
304682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
304782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3048bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
304982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
30504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
30514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
30523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
30544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
30553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
30574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
30584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
30594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
30604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
30613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3062ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
30633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3064ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3065ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3066ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
30679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
30689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
306941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
307041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
307141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
307224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
307324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
30749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
30759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
307641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
307741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3078b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3079b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3080b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3081b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3082b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3083e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3084e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
30854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
308682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
308782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
308882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
308982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
30903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
309186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
30923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30932047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
30943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
30952047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3096bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
309782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
30985f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
30995f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
31005f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
31013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
310286efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
31033e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
31055f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
310674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
31075f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
31085f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
31095f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
311082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
311182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
31121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
31133e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
311474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
31153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3117888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
31184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3119ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
31203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
31213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
31223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
31233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3125ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3126ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3127875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
31289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
31294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
31302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
31312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
313274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
313382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
313482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3135c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
313682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
313782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3138ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3139ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3140ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
314182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
314282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3143c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
31449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
31459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
31469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3147ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
314882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
314974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
315082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
315182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
315274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
315382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
315482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
315582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
315682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
315782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
315874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3159e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3160e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3161e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3162e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3163e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3164e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3165e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3166e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3167e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3168e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3169e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3170e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3171e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3172e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
3173e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        for (size_t l = 0; l < count; l++) {
3174e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            const sp<Layer>& layer(currentLayers[l]);
3175e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
3176e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3177e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3178e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
317982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
318082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
318182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
318282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
31833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
318474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
31853e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
31879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
31889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
318974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
319082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
319182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
319282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
319382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
319482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
319582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
319948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3200db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
320148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
320248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
320348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
320448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
320548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
320648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
320748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
320848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
320948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
321048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
321148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
321248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
321348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3214cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3215cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
321663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
321763f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
321863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
321963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
322063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
322163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
322263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
322363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
322463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
322524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
322663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
322763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
322863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
322963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
323063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
323163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
323263f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
323363f165fd6b86d04be94d4023e845e98560504a96Keun young Park
32346e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3237041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
3239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3240d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3241d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
32422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3243c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3248a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
32493bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
325099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
32516e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3252375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
32541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
32551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
32561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
32571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
32581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
32591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
32601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
32611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
326299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
326399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
32646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
32651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
32661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
32671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
32706e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
32716e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
32726e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
32736e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
32746e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
32756e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
32766e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
32776e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
32786e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
32796e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
32801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3283b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
328499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3285375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3286375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3287375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3288e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3289375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
329401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
329535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
330053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
330153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
330453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3307cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3308e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3309e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3310e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3311e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3312cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
33144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
33154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
33164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
33174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
331853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
331953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
332053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
332153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
332253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
332353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3324a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3325a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3326a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3327a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3328a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3329a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
333101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3334b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
333512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
33394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
33404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3341ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3342ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3343ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3344ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3345ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3346ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
33479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
33489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
33499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
33519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
33529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
33549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
33559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
33579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
33589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3359ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3360ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
33619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3362ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
33639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3364ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3365ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3366ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
33679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
33689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
33699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
33709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
33719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
33729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
33739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
33749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
33759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3376794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
33779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
33789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
33799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
33809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
33819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
33829c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
33839c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
33849c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
33859c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
33869c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3388f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3389f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3390f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3391645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3392645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3393f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3394f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3395ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3396ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3397ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3398ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3399ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3410468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3411468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3412468051e20be19130572231266db306396a56402bIrvel                if (n) {
3413468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3414ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3415468051e20be19130572231266db306396a56402bIrvel                }
3416468051e20be19130572231266db306396a56402bIrvel                else{
3417468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3418468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3419468051e20be19130572231266db306396a56402bIrvel                }
3420468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3421468051e20be19130572231266db306396a56402bIrvel            }
34228cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
34238cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
34248cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
34258cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
34268cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
343253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
343387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
343499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
343553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
343653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
343759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
34382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
34392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
344059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
34412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
34422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
34432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3444b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3445b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3446b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3447b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
34482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
34492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3450b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3451b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3452b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3453b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3454b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3455b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3456b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3457b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3458b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3459b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3460b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3461b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3462b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3463b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
34642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
34652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
34662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
34672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
34682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3469b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
34702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
34712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
34722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
34732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
34752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
34762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
34772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
34782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3480b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3481b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3482b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
34832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
34842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3485c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
34862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
34872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
34882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
34892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3490b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3491b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3492b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3493b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
34942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
34952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
34962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3497b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3498b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3499b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
35002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
35012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
35022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3503c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
35042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3507b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
35082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
35092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
35102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3511b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3512b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3513b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3514b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3515097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
35162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3517b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
35182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3523c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3524b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3525b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
352653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3527b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
352853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
352953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
353053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
353153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3532b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3533b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3534b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
35352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
35362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
35372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
35382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
35392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
35402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3542b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
35432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3544aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
35452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3546b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3547b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3548b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
35492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
35502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
35522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
35552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3556c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3557ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3558c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
35592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
35612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
35642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35665ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
35675ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
35685ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3569b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
35705ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3571c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3572c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3573c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3574c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3575c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3576c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3577c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3578c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3579c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3580c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3581c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3582c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3583c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3584c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3585c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3586c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3587c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3588c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3589c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3590c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3591c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
35922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
35932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
35942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
35952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3596c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
35972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
35982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3599c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3600c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
36012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3602b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
36032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3607c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3608ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                int32_t minLayerZ, int32_t maxLayerZ,
3609b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3610b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3611b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
36122a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3613c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
36142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3615c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3616b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3617b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
36182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
36192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
36212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
36222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
36242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
36252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3627c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3628b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3629097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
36302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
36312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
36332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
36352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
36362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
36372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
36382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
36402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
36412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
36422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3643c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3644b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
36452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
36472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
36482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
36492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
36502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3651118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3652118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3653180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3654180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3655180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3656c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3657ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3658c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3659180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3660180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
36613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3662180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3663180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
366489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
366589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
366689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
36670e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3668180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3669c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3670c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3671c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3672c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3673c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3674c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3675c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3676c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3677c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3678c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3679c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3680be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3681be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3682c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3683c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3684c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3685c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3686be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3687be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3688c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3689c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3690180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
36913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3692180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3693180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3694c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3695c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
36963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3697180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3698180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
36993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3700180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
37012047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
37021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3703180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3704180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3705180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3706180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3707c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3708180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3709180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3710180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3711180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
37122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3713180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3714931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3715180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3716180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3717180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
37182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
37192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
37202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3721c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3722ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3723b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
3724b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
372574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3726fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3727fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3728180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
37293502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
37303502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
37313502416204d9dbd905012ee586d8bd145323809fDan Stoza
37323502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
37333502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
37343502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3735180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3736180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3737180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3738180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3739180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3740180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3741180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3742180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3743180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3744180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3745b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
37462047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
3747b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
3748b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
3749b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                state.z <= maxLayerZ && layer->isVisible() &&
3750b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                layer->isSecure()) {
3751b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            secureLayerIsVisible = true;
3752b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
37532047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3754b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
3755b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
3756b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
3757b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
3758b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3759b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
37600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
37610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
376283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
3763605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
3764605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
3765605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
3766605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
3767605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
3768605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
3769605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
3770605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
37710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
377274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
37735a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
37745a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
37753ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
37763ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
37772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
37780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
37790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
37804ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
37810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
37820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
37832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
37840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
37850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
37860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
37870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
37880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
37890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
37900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3791866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
37920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
37930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
37940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
37950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
37960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
37973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
37983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
37993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
38003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
38010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
38020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
38030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
38040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3805c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3806c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3807c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3808d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3809866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3810866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3811866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3812866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3813866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3814866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
38159707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
38169707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3817866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3818866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3819866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
38202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3821866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3822866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3823866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3824866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3825866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3826866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
38272d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3828866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3829866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3830866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3831866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3832866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3833866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3834866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3835866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3836866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3837866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3838866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3839866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3840866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3841866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
38422d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3843866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
38442d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
38452d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3846d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3847d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3848d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3849d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3850d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3851d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3852d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3853d555684cb36dfb959694db76962e570184f98838Mathias Agopian
38540aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
38550aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
38560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
3857f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
3858f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
38590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
38600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
38610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
38620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
38630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
386474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3865f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
3866f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
3867f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
3868f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
386974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
38700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
38710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
387274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
38730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
387474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
387574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
387674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
387774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
387874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3879d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3880ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) {
3881fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3882d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3883d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3884d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3885fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3886fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3887fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3888fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3889fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3890fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
38912047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        size_t i = 0;
38922047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
3893fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3894fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3895fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3896fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
38979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
3898fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
38992047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    i, layer->getName().string(), state.layerStack, state.z,
3900fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
39012047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            i++;
39022047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
3903fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3904ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
3905ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
39061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
39071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
39082047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
39092047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInZOrder(consume);
3910921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3911921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
39122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
39132047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInReverseZOrder(consume);
3914921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3915921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
39173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
39203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
39213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
39223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
39243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
39253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3926