SurfaceFlinger.cpp revision 1f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9
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"
721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr#include "LayerVector.h"
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
77a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
81ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
82875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
83ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
84875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
91fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
92fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
93ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
94ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12899b49840d309727678b77403d6cc9f920111623fMathias Agopian
12999b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
13099b49840d309727678b77403d6cc9f920111623fMathias Agopian
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1324f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
136076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
1371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded(false),
13852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
139875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1444b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1468afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
148a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
153ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
154ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
155468051e20be19130572231266db306396a56402bIrvel        mInterceptor(),
1564a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
157faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
158948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
160b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
161b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
162b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
1631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLastSwapTime(0),
1641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mNumLayers(0)
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
166a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
171b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
17250210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
173b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1778afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1788afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1798afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
18063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
18163f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
18263f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
18363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1848afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
185c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
186c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
187c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
188c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
189c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
190c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
1918cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
1928cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    property_get("debug.sf.disable_hwc_vds", value, "0");
1938cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    mUseHwcVirtualDisplays = !atoi(value);
1948cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
19563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard
19663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    property_get("ro.sf.disable_triple_buffer", value, "0");
19763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    mLayerTripleBufferingDisabled = !atoi(value);
19863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
20499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
20599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
208a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
209a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
210a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
213c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
21499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
21599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
21699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
21713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
21813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
21999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
22099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
221a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
22299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
22399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2247e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22696f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
22796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
22896f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
22996f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
23096f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
236dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
247c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
253e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
25553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2568dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
258ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
260e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2736c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
276ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2786c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2796c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2806c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
281692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
2829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
283692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
284692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
285692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
286692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
28753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
288692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
289ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
290692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
291692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2939e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
297692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
299e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
3019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
3029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
3039a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
3049a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
310a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3113330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3141f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3191f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3201f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
321a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
322a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
323a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3240a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3250a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3260a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3270a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
338921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
340921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
341921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
342921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
344921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
345921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3485167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3494a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3504a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3510a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3520a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3534a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3544a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
355db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
356db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
357db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
358db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
359db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
360db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
365db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3674a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3735167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
379faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
380faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3815167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
388faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
389faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
390faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
417db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4184a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
419db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
421db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
422db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
423db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
424db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
425db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
426faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
430db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
431faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
432a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4340a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4355167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4360a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
441faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
442faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
443faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4444a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4454a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
446faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4495167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4505167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4510a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
455faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
457db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
458db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
460faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
462c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
463c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
464c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
465c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
466c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
467c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
468c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
469c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
470c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
471c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
472c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
473c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
474c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
475c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
476c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
477c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
478c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
479c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
480c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
481c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
482c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
483c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
484c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
485c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
486faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
487a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
496692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
500ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
503ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
505a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
506acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
50741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
50835520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
50941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
51041a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
51141a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
51241a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
517f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc = new HWComposer(this);
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
523b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
525875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
526875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
527875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
528a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
529da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
530da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
531da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
5339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
534a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
535a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
536d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
537d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
538d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
53992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
54092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5418630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
54213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
54313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
54413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
5454e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
5464e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
547a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
548a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
5513ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5523ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
553a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
554a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
555a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
556a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
557a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
558a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
559875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
560875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
561a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
562a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
563875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
564875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
565a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
566a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
568d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
569582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5702adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
571134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
572097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
574134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
575134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
576069b365163470d2736eb6f591c354d208b5da23bBrian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps(
5773890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        std::vector<FrameEvent>* outSupported) const {
578069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    *outSupported = {
5793890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::REQUESTED_PRESENT,
5803890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::ACQUIRE,
581f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::LATCH,
5823890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::FIRST_REFRESH_START,
583f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::LAST_REFRESH_START,
5843890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::GL_COMPOSITION_DONE,
5853d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        getHwComposer().presentFenceRepresentsStartOfScanout() ?
5863890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson                FrameEvent::DISPLAY_PRESENT : FrameEvent::DISPLAY_RETIRE,
587f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson        FrameEvent::DEQUEUE_READY,
5883890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson        FrameEvent::RELEASE,
589069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    };
590069b365163470d2736eb6f591c354d208b5da23bBrian Anderson    return NO_ERROR;
591069b365163470d2736eb6f591c354d208b5da23bBrian Anderson}
592069b365163470d2736eb6f591c354d208b5da23bBrian Anderson
5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
59523e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5997aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
6007aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
6017aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
602692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6039e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
604692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6051604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6061604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6071604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6081604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6091604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6101604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6111604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
612c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
6198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
6208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
6218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
6228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
6238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
6248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
6258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
6268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
6278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
6288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
6298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
6301604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
6347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
6379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
6407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
6417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
6457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
6467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
6477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
6677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
67091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
6719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
67291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
67391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
67491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
67591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
67691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
67791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
67891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
67991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
68091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
68191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
68291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
68391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
6849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
6859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6887f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6897f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
69028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
6918b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6928b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
695dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
69689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
69767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
69867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
69967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
70067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
70167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
70267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
70367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
70467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
70567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
70667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
70767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
70867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
7109f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    if (display == NULL) {
7119f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        ALOGE("%s : display is NULL", __func__);
7129f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        return BAD_VALUE;
7139f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    }
71424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
71524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
71624a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
71724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
71824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
7197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
720dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
7226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
7346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
7386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
7396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
7406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
7426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
7436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
7446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
7456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
7466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
7476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
7486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
7496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
7506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
7517306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
7527306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
753784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
7549ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7557306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
75628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
7577306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7617306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7636c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
773888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
774c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
81628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
81728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
81828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
82028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
82128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
82228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
82328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
82428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
82528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
82628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
82728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
82828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
82928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
83028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
85528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
85628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
85728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
85828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
85928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
86028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
86128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
86728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
86828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
86928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
870c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
871d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
872d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
873d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
874d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
875d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
876d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
877d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
878d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
879d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
880d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
881d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
882d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
883c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
884c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
885c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
886c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
887c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
888c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
889c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
890c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
891c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
892c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
893c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
894c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
895c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
896c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
897c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
898c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
899c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
900c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
901c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
902c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
903c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
904c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
905c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
906c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
907c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
908c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
909c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
910c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
911c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
912c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
913c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
914ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
915c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
916c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
917c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
918c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
919c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
920c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
921c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
922c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
923c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
924c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
925c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
926c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
927c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
928c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
929c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
930c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
931c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
932c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
933c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
934c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
935c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
936c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
937c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
938d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
939d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
940d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
9418aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
942bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
943bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
94599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
94899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
95299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
95699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
95999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
96099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
96199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
96299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
963c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
96499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
96599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
96699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
96799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
968c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
96999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
97099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
97199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
97299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
97399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
97499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9764f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
9774f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
9784f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
9794f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
98099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
982faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
983faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
984948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
985faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
986d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
987d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
988faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
98943601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
990faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
991faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
992948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
993faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
994faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
995948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
996948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
997948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
9980a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
9990a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
1000948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
1001948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1002948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
10039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
10049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
1005faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1006faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
1008faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1009faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
1010faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1011d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1012d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
1014faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1015faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1016faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1017948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1018faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1019faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1020d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1021d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1022faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1023faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1024faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1025948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1026948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1027948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1028faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1029faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
10304a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
10314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
10324a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
10330a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
10344a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
10354a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
10364a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
10379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
1038d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1039faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1040d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1041d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1042d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1043d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1044faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1045148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1046d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1047d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1048d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1049d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1050d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1051d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1052148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1053148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
10619e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer,
10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                new GraphicBufferAlloc());
10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
10799e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1080692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
10819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
10829e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1083692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1084692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
10859e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
10869e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
10879e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10889e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
10893ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
10908630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10918630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1093faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
10949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
10968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10978630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
10991c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
110099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
11016b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
11025018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
11035018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
11045018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence->getSignalTime() == INT64_MAX;
11055018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1106c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
11075018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
11085018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
11095018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
11105018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
11116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
11126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
11135878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
11146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
11155878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
11165878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
11175878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
11186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
11196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
11206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
11236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
11246b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11296b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1130c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard    uint32_t transactionFlags = peekTransactionFlags();
11314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
113287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
11336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
11344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
11364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11386b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1139cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
11406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
11414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
11423a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
11434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1144cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
114514cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
114640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
114705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
1148d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    preComposition(refreshStartTime);
114905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
115005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
115105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
115205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
1153d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    postComposition();
115405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
115511d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
1156bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1157bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1158bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1159bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1160bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1161bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1162bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
116314cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
11649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1165cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1166cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1167cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1169cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1170cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1171cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1172cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1173cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1174cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1175cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1177cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1178cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1179cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1180cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1181cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1182cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1183cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1184cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
11853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
11863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
11873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1188da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1189cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1190cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1191cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1192cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1193cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1194cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1195cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1196cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1197cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1198bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
11999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
12007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
12017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
12027bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
12037bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
12047bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
12057bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
12069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
12079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1208bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1209cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1210cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1211d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
12159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
12172047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
12182047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        if (layer->onPreComposition(refreshStartTime)) {
1219cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1220cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
12212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
12222047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
1223cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1224cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1225cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1226cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1227a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1228d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::postComposition()
1229cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
12329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
12333546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    // Release any buffers which were replaced this frame
1234f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson    nsecs_t dequeueReadyTime = systemTime();
12353546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    for (auto& layer : mLayersWithQueuedFrames) {
1236f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson        layer->releasePendingBuffer(dequeueReadyTime);
12373546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    }
12383546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson
1239d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
12403d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12413d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
12423d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
12433d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime =
12443d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
12453d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
12463d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
12473d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
12483d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
12493d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mGlCompositionDoneTimeline.updateSignalTimes();
12503d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12513d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    sp<Fence> displayFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
12523d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    auto displayFenceTime = std::make_shared<FenceTime>(displayFence);
12533d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.push(displayFenceTime);
12543d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.updateSignalTimes();
12553d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
12563d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    const std::shared_ptr<FenceTime>* presentFenceTime = &FenceTime::NO_FENCE;
12573d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    const std::shared_ptr<FenceTime>* retireFenceTime = &FenceTime::NO_FENCE;
12583d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->presentFenceRepresentsStartOfScanout()) {
12593d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        presentFenceTime = &displayFenceTime;
12603d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
12613d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        retireFenceTime = &displayFenceTime;
12623d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
12632047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
12642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
12652047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                *presentFenceTime, *retireFenceTime);
1266e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
12672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            recordBufferingStats(layer->getName().string(),
12682047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    layer->getOccupancyHistory(false));
1269e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
12702047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
12714b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
12723d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (displayFence->isValid()) {
12733d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        if (mPrimaryDispSync.addPresentFence(displayFence)) {
1274faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1275faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1276948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1277faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1278faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1279faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
12805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
12812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1282faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1283faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1284faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1285faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
12864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
12874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
12884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
12893d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        if (displayFenceTime->isValid()) {
12903d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson            mAnimFrameTracker.setActualPresentFence(
12913d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                    std::move(displayFenceTime));
12924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
12934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
12944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
12959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
12969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
12974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
12984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
12994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
13004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1301b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1302b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1303b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1304b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1305b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1306b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1307b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1308b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1309b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1310b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1311b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1312b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1313b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1314b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1315b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1316b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1317b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1318b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1319b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1320b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1321cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1322cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1323cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
13249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
13269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1327cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
132852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1329cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
133087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
133187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1332ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
133392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1334ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1335ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Vector<sp<Layer>> layersSortedByZ;
13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
13389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Transform& tr(displayDevice->getTransform());
13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect bounds(displayDevice->getBounds());
13409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (displayDevice->isDisplayOn()) {
13412047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                computeVisibleRegions(
13429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getLayerStack(), dirtyRegion,
13439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        opaqueRegion);
13447e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
13452047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mDrawingState.traverseInZOrder([&](Layer* layer) {
13461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    if (layer->getLayerStack() == displayDevice->getLayerStack()) {
1347a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1348a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1349a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1350a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1351ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
13529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // Clear out the HWC layer if this layer was
13549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // previously visible, but no longer is
13559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
13569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    nullptr);
1357ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
135887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
13592047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                });
13603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
13629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.set(bounds);
13639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.subtractSelf(
13649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    tr.transform(opaqueRegion));
13659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->dirtyRegion.orSelf(dirtyRegion);
13663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
13673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1368cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
13693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1370cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
13719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
13739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1374028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1375b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1376b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1377b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1378b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1379b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1380b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1381b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1382b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1383b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1384b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1385b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1386b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1387b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1388b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1389b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1390b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1391b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1392b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1393b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1394b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1395b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
13967143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1397b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1398b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1399b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1400b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1401028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1402028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
14039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool foundLayerWithoutHwc = false;
1413ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                for (size_t i = 0; i < currentLayers.size(); i++) {
14141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    const auto& layer = currentLayers[i];
14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
14189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
14219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            foundLayerWithoutHwc = true;
14229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1423a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1424a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1425a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1426ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    layer->setGeometry(displayDevice, i);
14279f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
14289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
142903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
143003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
143103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
143203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
14339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
143403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
14359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
14379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
14399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
14439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
14449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
14469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
14479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
14489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
14499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
14509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
145238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
145352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
14549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
14559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
14569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
14597bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14607bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14617bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14627bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
14637bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
14649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
14659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
14669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1467cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
146852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1469cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1470cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
14719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
14729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
147352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
147492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1477cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1478cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
147902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
148002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
148102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
148202b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1483cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1484cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1485cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
148687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
14874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
148852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1493841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
14949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1495b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1496a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1497a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1498c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
14999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
15009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
15017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
15027bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
15037bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
15049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
15059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
1506a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard            mHwc->presentAndGetReleaseFences(hwcId);
15079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
15082dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1509b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
15109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
15119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
15129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
15139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
15149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
15159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
15169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
151752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
15189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
15199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
15209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
15219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1522ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1523e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1524e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1525a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1526a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
15276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
15286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
15296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
15306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
15316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1536841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1537841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
15387cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
15397cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
15407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
15417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
15427cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
15437cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1544ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1545ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1546ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1547ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1548ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1549ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1550ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1551ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1552ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1553ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
155587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1556ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1557ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1559ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1560ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
15613d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
15643d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
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).
17811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            uint32_t layerStack = layer->getLayerStack();
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     */
18191f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
18201f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (mLayersAdded) {
18211f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = false;
18221f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        // Layers have been added.
18233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
18243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
18253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
18263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
18273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
18283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
18293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
18303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
18312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
18321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
18333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
18343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
18353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
18363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
18371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                Region visibleReg;
18381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                visibleReg.set(layer->computeScreenBounds());
18391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                invalidateLayerStack(layer->getLayerStack(), 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
18671f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& l : mLayersPendingRemoval) {
18681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            recordBufferingStats(l->getName().string(),
18691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    l->getOccupancyHistory(true));
18701f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            l->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;
18801f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mDrawingState.traverseInZOrder([](Layer* layer) {
18811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->commitChildList();
18821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    });
18832d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
18842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
18854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18882047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
188987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1891841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
18929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
1893841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
189887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19002047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
1901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
19021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
19051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != layerStack)
19062047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            return;
190787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1908ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1909ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1910ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1915ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1916ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1917ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1921ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1922ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1923ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1924ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1926ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1927a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1928a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1929a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1930a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1931a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1932a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1933a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1934a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1935a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1936a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1938ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1939da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
19404125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
19411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Rect bounds(layer->computeScreenBounds());
1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
19431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Transform tr = layer->getTransform();
1944ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
194722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
194822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
194922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
19504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
195122f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
195222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
195322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
19544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1955ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
19581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                const int32_t layerOrientation = tr.getOrientation();
19599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
1960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1963ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1970ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1972ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
19814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1984a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1985ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1986ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1987ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1988ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1989ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1990ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1991ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1992ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1993ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1994ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1995a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1996ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
19974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
19984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1999ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
2000ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
200587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
2006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2007ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
2008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
20098b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2010a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
2011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
2012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
2013a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
2014a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
20152047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
2016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
2018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
202087baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
202187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
202292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
20234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
20244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
20254297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
202692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
202792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
202887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
202987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
20306b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
20339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2034d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    nsecs_t latchTime = systemTime();
203599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
20376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
203851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
203951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
204051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
204151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
204251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
204351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
204451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
204551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
204651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
204751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
20482047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
20496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
20506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
20516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
20522047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mLayersWithQueuedFrames.push_back(layer);
2053ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2054ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
20556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2056ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2057ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
20586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
20592047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
20602047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
20619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
2062d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
2063ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
20641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        invalidateLayerStack(layer->getLayerStack(), dirty);
20654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
20664da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
20673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
20686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
20706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
20716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
20729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
20736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
20746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
20756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
20779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
2078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2080ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2081ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
20829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2083ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2084ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
208599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2086830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition(
2087830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        const sp<const DisplayDevice>& displayDevice,
208887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20907143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
20917143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
20927143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
20937143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
2094830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
20957143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
20969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
20977143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
20987143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
20997143316af216fa92c31a60d4407b707637382da1Dan Stoza
21009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
21019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
210287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
210387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2104b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
2105830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2107830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    uint32_t flags = displayDevice->getFlags();
21080f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
210929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
211029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
211129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
2112830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        dirtyRegion.set(displayDevice->swapRegion.bounds());
2113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
21140f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
211529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2116df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
211795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
21180f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
2119830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->swapRegion.bounds());
2120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
212129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
2122830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->bounds());
2123830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            displayDevice->swapRegion = dirtyRegion;
2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2127830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
2128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21299c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
2130830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2131da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2132da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2133830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapBuffers(getHwComposer());
2134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
21379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
21409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
21419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
21429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
21449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
21459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
21469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
21479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
21489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
21499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
21509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
21529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2154a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
21559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2156c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
21583f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
21593f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
21603f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
21613f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
21623f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2163c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2164a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2165a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
21669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
21679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2168b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2169b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2170b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
21713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2172b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
21739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2174b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2175766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
21769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2177766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2178766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2179766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2180766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
21819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2182766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2183766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
21849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2185766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2186766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2187766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2188766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2189b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
219087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2191b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
21929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2193b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2194a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2195f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2197766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2198f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2199f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
22009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
22019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2202f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2203f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2204f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2205f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
22063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2207f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
22089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
22099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
22103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2211f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2212f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
221385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
22144b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
221585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
221685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
221785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
22184b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
22199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
22209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
22219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
222285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
22239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
22249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
22259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
22269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
22279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
22289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
22299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
223085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
22329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
22339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
22349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2235ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
22369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
22379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
22389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2239cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
22411748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard                            layer->clearWithOpenGL(displayDevice);
2242cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
224385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
224485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
22459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
22469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
224785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2248a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
22499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2250da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2251cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
22529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
22539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2254a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
22559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
225685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
225785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
225885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
22599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
226085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
22619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
226285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
226485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
22654b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
22664b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2267f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
22689f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
22699f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
22709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
22719f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2272f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
22739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
22743f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2277830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
2278830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    const int32_t height = displayDevice->getHeight();
22793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
22803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22837d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2284ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
22856710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
22861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& lbc,
22871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& parent)
22881b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
22897d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
22907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
22917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
22921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (mNumLayers >= MAX_LAYERS) {
22937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
22947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
22951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (parent == nullptr) {
22961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            mCurrentState.layersSortedByZ.add(lbc);
22971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        } else {
22981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            parent->addChild(lbc);
22991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
23007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
23011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = true;
23021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mNumLayers++;
23037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
23047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
230596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2306ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
23074f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
23087d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
230996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
231096f0819f81293076e652792794a961543e6750d7Mathias Agopian
231122851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
231296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
231322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    sp<Layer> layer = weakLayer.promote();
231422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    if (layer == nullptr) {
231522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        // The layer has already been removed, carry on
231622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        return NO_ERROR;
231722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    }
231822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza
23191f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const auto& p = layer->getParent();
23201f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
23211f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.layersSortedByZ.remove(layer);
23221f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
23231f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (index < 0) {
23241f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        ALOGE("Failed to find layer (%s) in layer parent (%s).",
23251f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->getName().string(),
23261f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (p != nullptr) ? p->getName().string() : "no-parent");
23271f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        return BAD_VALUE;
2328598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
23291f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
23301f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersPendingRemoval.add(layer);
23311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersRemoved = true;
23321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mNumLayers--;
23331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    setTransactionFlags(eTransactionNeeded);
23341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    return NO_ERROR;
2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2337c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() {
2338dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2339dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2340dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
23413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
234899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23538b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
23548b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
23558b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
23568b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
23578b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
23587c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2359698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
236028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2361e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
23622d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
23632d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
23642d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
23652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
23667c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
23672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
23682d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
23697c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
23707c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
23717c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
23722d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
23732d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
23742d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
23752d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23762d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
23772d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2378e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2379e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2380e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2381e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2382b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2383b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2385698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2386698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2387d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2388d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2389d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2390d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2391d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2392d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2393d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2394d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2395097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2396d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2397d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2398d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2399d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2400d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2401d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2402d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2403d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2404698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2405386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
24062a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
24072a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
24082a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
24092a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
24102a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
24112a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
24122a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
241328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2414ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2415ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2416ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2417468051e20be19130572231266db306396a56402bIrvel
2418386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
241928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2420698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2421386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2422386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2423386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
24242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
24252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
24262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
24272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2428386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
24292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2430386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2431386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2432386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2433386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
24342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
24352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2436386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2437386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2438cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
24449a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
24459a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
24469a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
24479a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2448e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
24499a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
24503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2453097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2461e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2462e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2463e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
246400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2466e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
247847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
247947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
248047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
248147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
248247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
248347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
248447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
248547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
248647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
248747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
249713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
250099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
250199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
250399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
250582364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2507e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
25091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            const auto& p = layer->getParent();
25101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (p == nullptr) {
25111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
25121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (layer->setLayer(s.z) && idx >= 0) {
25131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.removeAt(idx);
25141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.add(layer);
25151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // we need traversal (state changed)
25161f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // AND transaction (list changed)
25171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
25181f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
25191f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else {
25201f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (p->setChildLayer(layer, s.z)) {
25211f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
25221f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
2523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2526e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2527e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2528e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
25319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2533e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2541e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2542231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2543e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2544e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2545e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2546e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
254799e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2548e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2550acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2551acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2552acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2553acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2555e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
25561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // We only allow setting layer stacks for top level layers,
25571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // everything else inherits layer stack from its parent.
25581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->hasParent()) {
25591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
25601f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        layer->getName().string());
25611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (idx < 0) {
25621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer without parent (%s) that "
25631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        "that also does not appear in the top level layer list. Something"
25641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        " has gone wrong.", layer->getName().string());
25651f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (layer->setLayerStack(s.layerStack)) {
2566e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2569e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2570e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2571e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
25737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
25747dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            layer->deferTransactionUntil(s.handle, s.frameNumber);
25757dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
25767dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
25777dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2578c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2579c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2580c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2581c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2582c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2583e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2584e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2585e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2586e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
25880ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
25890ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
25904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
25911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
25921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        sp<Layer>* parent)
2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25946e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2595921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
25966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
25974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
25986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
25998b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
26004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
26014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
26024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
26034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
26043165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
26053165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
26064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
26074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
26084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
26103165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
26114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
26124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
26134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
26144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
26154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
26164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26207d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
26217d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
26237d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
26241f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result = addClientLayer(client, *handle, *gbp, layer, *parent);
26257d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
26267d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
26277d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
2628ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
26297d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
26307d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
26314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
26354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
26364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
263992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
26458f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
26504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
26514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
26524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2653b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
26554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
26564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
26574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
26614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
26624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
26654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2666b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
26674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2668118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2669118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2670ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
26719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
26726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
26736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
26746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
26756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
2676ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
26776710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
26786710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
26796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
26809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
26819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
26829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
26839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
268413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26866710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
26876710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
268822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    return removeLayer(layer);
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2691b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2692b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
269313a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
269401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
269513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
269613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
269713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
269801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
269901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2700692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
270101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
270213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
27034c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
27044c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
270547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
270647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
270713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
270813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
27092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
27106547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
27119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
27129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
27136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
271413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
271513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
271613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
271713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
271813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
271913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
2720c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
272113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
272213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
272313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
272413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
272513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
272613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
272713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
272813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
272913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
27302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
27312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
27322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
27332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
27342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
27352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
273613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
27372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
27382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2739c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2740c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2741c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
27422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
27432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
27442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
27452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
27462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2747c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2748ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
2749ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
2750ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
2751ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
2752ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
2753ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
2754ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2755ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
2756ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
2757ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
27582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
2759f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
27602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2761c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2762c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2763c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2764948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2765c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2768b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
27692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
2770f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2771f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2772f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
2773f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
2774f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
2775f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
27762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2777f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
2778f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2779f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
2780f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
2781f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
2782f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2783c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2784948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2785948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2786cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2787cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2788cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2789c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
27902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
27912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
27922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
27932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
27942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2795b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
27992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2800db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2801db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
28022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2803b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
28042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
28052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
28062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2807b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
28082c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2809db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
28102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
28117306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
28129e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
28132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
28142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2815db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
28162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2817db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2818b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2819b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2820b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
28212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2822db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2823b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2824b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2825b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2826b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
283099b49840d309727678b77403d6cc9f920111623fMathias Agopian
2831bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2832bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2833bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2834bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2835bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
283674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2837bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2839fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
28409795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
28419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2842fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2843fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
28449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2845fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2846fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2847fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
28489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
28499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
285082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
285182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
285225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
285325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
285425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
285525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
285625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
285774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
285835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
285925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
286025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
286125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
286225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
286382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
286474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
286535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
286682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
286725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
286825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
286925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
287025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
287174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
287235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
287325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2874c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2875c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2876c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2877c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2878c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2879c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2880c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2881b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2882b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2883b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2884b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2885b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2886b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2887b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
288840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
288940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
2890d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    (args[index] == String16("--frame-events"))) {
289140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
2892d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                dumpFrameEventsLocked(result);
289340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
289440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
2895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
28961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
289782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
289874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
289982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
290048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
290182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
290282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
290348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
290482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
290582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
290682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
290782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
290848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2909c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2910c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
291125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
29122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
291374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
29142047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
291525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
291625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
291782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
291874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
291982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
292082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
292182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
292282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
292382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
292482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
292548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
29269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
29279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
292886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
29294b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
29304b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2931d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
29324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
29332047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
29344b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2935d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
29364b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
29372047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
293882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
293982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2940ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
294125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2942c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
294325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
294425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
294525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
294625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
294725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
294825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
294925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
29502047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
295125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2952d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
295325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
29542047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
29554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2956d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
295725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
295825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
29596547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
29606547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
29616547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
29622047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
29636547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
29642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
29656547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
29666547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
29676547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
29686547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
296963a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const
29704803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
297163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" [sf");
29724803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
297363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" HAS_CONTEXT_PRIORITY");
29744803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
29754803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
297663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" NEVER_DEFAULT_TO_ASYNC_MODE");
29774803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
297863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    if (isLayerTripleBufferingDisabled())
297963a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard        result.append(" DISABLE_TRIPLE_BUFFERING");
298063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append("]");
29814803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
29824803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2983b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2984b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2985b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2986b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2987b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2988b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2989b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2990b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2991b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2992b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2993b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2994b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2995b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2996b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2997b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2998b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2999b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
3001e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
3002e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3003e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
3004e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
3005e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
3006e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
3007e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3008e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
3009e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
3010e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
3011e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
3012e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3013e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
3014e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
3015e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3016e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3017e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3018d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
3019d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("Layer frame timestamps:\n");
3020d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3021d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
3022d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const size_t count = currentLayers.size();
3023d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    for (size_t i=0 ; i<count ; i++) {
3024d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        currentLayers[i]->dumpFrameEvents(result);
3025d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
3026d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
3027d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3028e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
3029e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
3030e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
3031e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
3032e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3033e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
3034e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
3035e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
3036e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
3037e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
3038e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
3039e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
3040e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3041e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
3042e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
3043e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
3044e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
3045e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
3046e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
3047e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
3048e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
3049e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3050e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3051e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3052e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3053e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3054e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3055e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3056e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3057e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3058e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3059e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3060e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3061e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3062e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
306374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
306474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
306582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
30663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
30673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
30683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
30693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
30703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
30713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
30723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
30743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
307582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
307682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
307782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
307882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
307982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
308082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3081bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
308282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
30834803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
30844803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
30853e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
30874803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
30883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
30904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
30914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
30924803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
30934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
30943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3095ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
30963e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3097ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3098ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3099ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
31009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
31019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
310241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
310341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
310441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
310524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
310624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
31079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
31089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
310941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
311041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3111b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3112b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3113b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3114b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3115b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3116e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3117e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
31184803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
311982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
312082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
31213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
31221f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
31233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31242047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
31253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
31262047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3127bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
312882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
31295f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
31305f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
31315f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
31323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
313386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
31343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31355f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
31365f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
313774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
31385f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
31395f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
31405f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
314182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
314282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
31431b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
31443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
314574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
31463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31471b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3148888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
31494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3150ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
31513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
31523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
31533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
31543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3156ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3157ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3158875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
31599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
31604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
31612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
31622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
316374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
316482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
316582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3166c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
316782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
316882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3169ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3170ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3171ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
317282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
317382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3174c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
31759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
31769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
31779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3178ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
317982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
318074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
318182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
318282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
318374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
318482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
318582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
318682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
318782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
318882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
318974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3190e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3191e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3192e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3193e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3194e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3195e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3196e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3197e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3198e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3199e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3200e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3201e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3202e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3203e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
32041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
3205e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
32061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
3207e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3208e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
320982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
321082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
321182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
321282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
32133e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
321474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
32153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
32169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
32179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
32189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
321974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
322082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
322182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
322282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
322382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
322482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
322582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
322813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
322948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3230db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
323148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
323248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
323348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
323448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
323548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
323648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
323748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
323848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
323948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
324048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
324148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
324248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
324348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3244cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3245cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
324663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
324763f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
324863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
324963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
325063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
325163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
325263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
325363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
325463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
325524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
325663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
325763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
325863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
325963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
326063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
326163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
326263f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
326363f165fd6b86d04be94d4023e845e98560504a96Keun young Park
32646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3267041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3268698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
3269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3270d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3271d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
32722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3273c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3278a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
32793bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
328099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
32816e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3282375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
32841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
32851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
32861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
32871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
32881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
32891b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
32901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
32911b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
329299b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
329399b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
32946e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
32951b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
32961b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
32971b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
33006e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
33016e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
33026e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
33036e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
33046e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
33056e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
33066e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
33076e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
33086e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
33096e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
33101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3313b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
331499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3315375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3316375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3317375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3318e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3319375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
332401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
332535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
333053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
333153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
333453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3336cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3337cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3338e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3339e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3342cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
33444d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
33454d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
33464d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
33474d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
334853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
334953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
335053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
335153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
335253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
335353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3354a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3355a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3356a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3357a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3358a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3359a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
336101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3364b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
336512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
33694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
33704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3371ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3372ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3373ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3374ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3375ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3376ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
33779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
33789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
33799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33809f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
33819f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
33829f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33839f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
33849f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
33859f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
33879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
33889f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3389ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3390ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
33919f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3392ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
33939f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3394ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3395ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3396ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
33979c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
33989c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
33999c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
34009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
34019c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
34029c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
34039c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
34049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
34059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3406794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
34079f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
34089f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
34099f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
34109c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
34119c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
34129c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
34139c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
34149c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
34159c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
34169c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3418f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3419f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3420f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3421645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3422645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3423f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3424f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3425ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3426ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3427ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3428ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3429ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3430db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3431db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3432db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3433db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3434db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3435db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3438db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3439db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3440468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3441468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3442468051e20be19130572231266db306396a56402bIrvel                if (n) {
3443468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3444ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3445468051e20be19130572231266db306396a56402bIrvel                }
3446468051e20be19130572231266db306396a56402bIrvel                else{
3447468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3448468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3449468051e20be19130572231266db306396a56402bIrvel                }
3450468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3451468051e20be19130572231266db306396a56402bIrvel            }
34528cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
34538cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
34548cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
34558cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
34568cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
346387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
346499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
346553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
346653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
346759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
34682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
34692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
347059119e658a12279e8fff508f8773843de2d90917Mathias Agopian
34712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
34722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
34732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3474b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3475b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3476b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3477b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
34782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3480b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3481b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3482b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3483b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3484b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3485b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3486b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3487b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3488b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3489b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3490b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3491b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3492b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3493b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
34942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
34952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
34962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
34972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
34982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3499b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
35002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
35012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
35022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
35032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
35052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
35062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
35072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
35082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3510b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3511b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3512b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
35132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
35142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3515c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
35162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
35172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
35182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3520b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3521b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3522b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3523b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
35242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
35252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
35262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3527b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3528b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3529b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
35302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
35312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
35322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3533c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
35342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3537b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
35382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
35392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
35402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3541b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3542b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3543b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3544b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3545097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
35462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3547b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
35482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
35492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
35502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3553c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3554b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3555b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
355653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3557b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
355853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
355953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
356053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
356153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3562b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3563b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3564b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
35652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
35662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
35672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
35682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
35692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
35702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3572b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
35732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3574aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
35752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3576b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3577b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3578b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
35792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
35802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
35822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
35852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3586c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3587ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3588c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
35892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
35912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
35942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35965ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
35975ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
35985ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3599b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
36005ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3601c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3602c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3603c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3604c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3605c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3606c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3607c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3608c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3609c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3610c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3611c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3612c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3613c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3614c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3615c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3616c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3617c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3618c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3619c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3620c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3621c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
36222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
36232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
36242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
36252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3626c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
36272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
36282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3629c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3630c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
36312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3632b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
36332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
36342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
36352a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
36362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3637c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3638ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                int32_t minLayerZ, int32_t maxLayerZ,
3639b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3640b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3641b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
36422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3643c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
36442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3645c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3646b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3647b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
36482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
36492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
36512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
36522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36532a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
36542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
36552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3656c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3657c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3658b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3659097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
36602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
36612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
36632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
36652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
36662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
36672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
36682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
36702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
36712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
36722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3673c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3674b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
36752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
36772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
36782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
36792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
36802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3681118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3682118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3683180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3684180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3685180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3686c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3687ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3688c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3689180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3690180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
36913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3692180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3693180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
369489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
369589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
369689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
36970e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3698180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3699c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3700c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3701c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3702c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3703c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3704c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3705c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3706c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3707c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3708c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3709c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3710be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3711be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3712c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3713c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3714c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3715c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3716be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3717be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3718c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3719c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3720180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
37213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3722180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3723180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3724c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3725c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
37263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3727180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3728180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
37293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3730180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
37311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // We loop through the first level of layers without traversing,
37321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // as we need to interpret min/max layer Z in the top level Z space.
37331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
37341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != hw->getLayerStack()) {
37351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
37361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
37371eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
37381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (state.z < minLayerZ || state.z > maxLayerZ) {
37391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
3740180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
37411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer* layer) {
37421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (!layer->isVisible()) {
37431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                return;
37441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
37451f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(true);
37461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            layer->draw(hw, useIdentityTransform);
37471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(false);
37481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
37491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
3750180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3751931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3752180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3753180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3754180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
37552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
37562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
37572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3758c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3759ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3760b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
3761b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
376274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3763fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3764fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3765180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
37663502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
37673502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
37683502416204d9dbd905012ee586d8bd145323809fDan Stoza
37693502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
37703502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
37713502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3772180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3773180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3774180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3775180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3776180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3777180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3778180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3779180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3780180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3781180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3782b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
37831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
3784b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
37851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if ((layer->getLayerStack() != hw->getLayerStack()) ||
37861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (state.z < minLayerZ || state.z > maxLayerZ)) {
37871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
3788b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
37891f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer *layer) {
37901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
37911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    layer->isSecure());
37921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
37931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
3794b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
3795b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
3796b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
3797b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
3798b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3799b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
38000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
38010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
380283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
3803605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
3804605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
3805605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
3806605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
3807605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
3808605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
3809605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
3810605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
38110aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
381274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
38135a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
38145a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
38153ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
38163ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
38172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
38180aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
38190aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
38204ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
38210aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
38220aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
38232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
38240aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
38250aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
38260aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
38270aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
38280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
38290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
38300aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3831866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
38320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
38330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
38340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
38350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
38360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
38373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
38383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
38393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
38403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
38410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
38420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
38430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
38440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3845c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3846c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3847c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3848d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3849866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3850866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3851866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3852866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3853866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3854866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
38559707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
38569707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3857866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3858866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3859866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
38602d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3861866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3862866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3863866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3864866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3865866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3866866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
38672d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3868866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3869866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3870866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3871866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3872866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3873866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3874866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3875866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3876866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3877866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3878866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3879866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3880866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3881866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
38822d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3883866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
38842d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
38852d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3886d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3887d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3888d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3889d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3890d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3891d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3892d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3893d555684cb36dfb959694db76962e570184f98838Mathias Agopian
38940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
38950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
38960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
3897f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
3898f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
38990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
39000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
39010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
39020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
39030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
390474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3905f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
3906f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
3907f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
3908f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
390974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
39100aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
39110aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
391274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
39130aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
391474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
391574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
391674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
391774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
391874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3919d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3920ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) {
3921fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3922d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3923d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3924d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3925fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3926fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3927fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3928fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3929fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3930fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
39311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
39322047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        size_t i = 0;
39331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& layer : mDrawingState.layersSortedByZ) {
3934fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
39351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ &&
39361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    state.z <= maxLayerZ) {
39371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->traverseInZOrder([&](Layer* layer) {
39381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
39391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            layer->isVisible() ? '+' : '-',
39401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            i, layer->getName().string(), layer->getLayerStack(), state.z,
3941fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
39421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    i++;
39431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                });
39441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
39451f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
3946fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3947ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
3948ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
39491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
39501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
39512047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
39522047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInZOrder(consume);
3953921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3954921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
39552047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
39562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInReverseZOrder(consume);
3957921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3958921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
39603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
39633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
39643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
39653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
39673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
39683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3969