SurfaceFlinger.cpp revision 412903fce3a93f411c85c54375a1851bfb370400
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>
3699b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar#include <dvr/vr_flinger.h>
3987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
405d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#include <ui/DebugUtils.h>
41c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
4267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
43c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
47e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.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"
741db73f66624e7d151710483dd58e03eed672f064Robert Carr#include "MonitoredProducer.h"
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
77a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
78a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
82ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
83875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
84ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
85875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
864b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
874351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Lee#include <configstore/Utils.h>
884b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
92fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
93fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
94fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
95fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
96fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
97ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
98ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
101c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard
1024351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Leeusing namespace android::hardware::configstore;
1034b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Parkusing namespace android::hardware::configstore::V1_0;
1044b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
10899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
10999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
11099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
11199b49840d309727678b77403d6cc9f920111623fMathias Agopian
11299b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
1130cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::vsyncPhaseOffsetNs;
1140cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::sfVsyncPhaseOffsetNs;
115c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglardbool SurfaceFlinger::useContextPriority;
116c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglardint64_t SurfaceFlinger::dispSyncPresentTimeOffset;
117a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglardbool SurfaceFlinger::useHwcForRgbToYuv;
118c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglarduint64_t SurfaceFlinger::maxVirtualDisplaySize;
119cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglardbool SurfaceFlinger::hasSyncFramework;
120050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool SurfaceFlinger::useVrFlinger;
1211971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglardint64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
1225d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterbool SurfaceFlinger::hasWideColorDisplay;
12399b49840d309727678b77403d6cc9f920111623fMathias Agopian
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1254f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
129076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
1301f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded(false),
13152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
13287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mHwc(nullptr),
13387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRealHwc(nullptr),
13487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mVrHwc(nullptr),
13587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRenderEngine(nullptr),
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1404b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1428afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14373d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
144a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
149ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
150ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
1510d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        mInterceptor(this),
1524a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
153faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
154948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
1591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLastSwapTime(0),
160050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mNumLayers(0),
161050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlingerRequestsDisplay(false)
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
163cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    ALOGI("SurfaceFlinger is starting");
1640cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1650cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1660cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
1670cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1680cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1690cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
1700cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
171cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
172cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
174c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    useContextPriority = getBool< ISurfaceFlingerConfigs,
175c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard            &ISurfaceFlingerConfigs::useContextPriority>(false);
176c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
177c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
178c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
179c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
180a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
181a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
182a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard
183c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
184c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
185c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard
186050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    // Vr flinger is only enabled on Daydream ready devices.
187050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    useVrFlinger = getBool< ISurfaceFlingerConfigs,
188050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            &ISurfaceFlingerConfigs::useVrFlinger>(false);
189050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
1901971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
1911971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);
1921971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard
1935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    hasWideColorDisplay =
1945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
1955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1988afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
199b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
20050210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
201b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
2048afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
2058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
2068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
2078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
20863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
20963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
21063f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
21163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
2128afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
213c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
214c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
215c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
216c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
217c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
218c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
2198cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
220642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    property_get("debug.sf.enable_hwc_vds", value, "0");
221642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    mUseHwcVirtualDisplays = atoi(value);
222642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
22363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard
224c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    property_get("ro.sf.disable_triple_buffer", value, "1");
225c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    mLayerTripleBufferingDisabled = atoi(value);
22663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
23099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
23199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
23299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
23399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
236a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
241c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
24299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
24399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
24499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
24613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
24799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
249a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
25099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
25199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2521db73f66624e7d151710483dd58e03eed672f064Robert Carrstatic sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
25396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
25496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
2551db73f66624e7d151710483dd58e03eed672f064Robert Carr        return client;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2571db73f66624e7d151710483dd58e03eed672f064Robert Carr    return nullptr;
2581db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2591db73f66624e7d151710483dd58e03eed672f064Robert Carr
2601db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
2611db73f66624e7d151710483dd58e03eed672f064Robert Carr    return initClient(new Client(this));
2621db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2631db73f66624e7d151710483dd58e03eed672f064Robert Carr
2641db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
2651db73f66624e7d151710483dd58e03eed672f064Robert Carr        const sp<IGraphicBufferProducer>& gbp) {
2661db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (authenticateSurfaceTexture(gbp) == false) {
2671db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2681db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2691db73f66624e7d151710483dd58e03eed672f064Robert Carr    const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
2701db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (layer == nullptr) {
2711db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2721db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2731db73f66624e7d151710483dd58e03eed672f064Robert Carr
2741db73f66624e7d151710483dd58e03eed672f064Robert Carr   return initClient(new Client(this, layer));
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
278dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
283e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
287e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
288e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
289c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
290e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
291e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
29753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2988dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
299e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
300ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
301e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
302e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
303e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3046c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
3056c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
3066c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3076c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
3086c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
3096c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
3106c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3116c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
3126c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3136c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
3146c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
3156c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
3166c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3176c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
318ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
3196c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
3206c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
3216c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
3226c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
323692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
3249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
325692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
326692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
327692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
328692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
32953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
330692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
331ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
332692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
333692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
3359e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
336e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
338e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
339692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
344b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
345b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
346b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
349a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3503330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3511f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3521f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3531f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3541f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3551f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
356921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3571f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3581f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
359050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (mVrFlinger) {
360050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      mVrFlinger->OnBootFinished();
361050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
362050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
3631f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
364a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
365a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
366a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3670a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3680a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3690a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3700a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
374921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
377921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
380921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
381921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
383921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
384921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
387921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
389faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
390faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3915167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3924a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3934a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3940a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3950a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3964a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3974a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
404faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
405faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
406faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
407faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
409faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
4104a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
411faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
412faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
413faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
414faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
415faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4165167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
420faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
422faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4245167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
426db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
430db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
431faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
434db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
435db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
438db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
439db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
440db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
441db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
442db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
445db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
446db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
447db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
448db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
449db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
450db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
451db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
452db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
455db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
457db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
458db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
460db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4614a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
462db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
463db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
464db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
465db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
466db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
467db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
468db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
469faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
470faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
471faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
472faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
473db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
474faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
475a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4760a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4770a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4785167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
480faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
481faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
482faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
483faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
484faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
485faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
486faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4874a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4884a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
489faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
490faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4910a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4925167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4935167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4940a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
495faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
496db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
497db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
498faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
499db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
500db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
501db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
502db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
503faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
504faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
505c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
506c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
507c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
508c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
509c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
510c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
511c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
512c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
513c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
514c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
515c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
516c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
517c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
518c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
519c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
520c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
521c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
522c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
523c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
524c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
525c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
526c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
527c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
528c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
529faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
530a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
531a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
532a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
5334b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park    ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);
5344b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
5359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
5369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
541692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
5429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
5439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
545ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
5469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
548ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
550a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
551acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
55241a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
55335520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
55441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
55541a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
55641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
55741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
562f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
566050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
567050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        "Starting with vr flinger active is not currently supported.");
5683cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    mRealHwc = new HWComposer(false);
56987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mHwc = mRealHwc;
5709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
571b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
573875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
5745c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    // Inform native graphics APIs whether the present timestamp is supported:
5755c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    if (getHwComposer().hasCapability(
5765c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott            HWC2::Capability::PresentFenceIsNotReliable)) {
5775c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott        property_set(kTimestampProperty, "0");
5785c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    } else {
5795c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott        property_set(kTimestampProperty, "1");
5805c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    }
5815c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott
582050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (useVrFlinger) {
583050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
584050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            mVrFlingerRequestsDisplay = requestDisplay;
585050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            signalTransaction();
586050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        };
587050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
588050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                                            vrFlingerRequestDisplayCallback);
589050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (!mVrFlinger) {
590050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            ALOGE("Failed to start vrflinger");
591050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        }
592050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
593050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
594875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
595875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
596a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
597da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
598da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
599da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
6019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
6027d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
603a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
604d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
605d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
606d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
60792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
60892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
6098630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
61013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
61113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
61213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
6134e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
6144e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
615b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread = new StartBootAnimThread();
616b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->Start() != NO_ERROR) {
617b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Run StartBootAnimThread failed!");
618b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
6213ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
6223ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
623a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
624b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Start boot animation service by setting a property mailbox
625b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // if property setting thread is already running, Start() will be just a NOP
626b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread->Start();
627b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Wait until property was set
628b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
629b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
630b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
631a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
632a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
633875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
634875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
635a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
636a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
637875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
638875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
639a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
640a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
642d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
643582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
6442adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
645134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
6460d48072f6047140119ff194c1194ce402fca2c0bRobert Carr    return authenticateSurfaceTextureLocked(bufferProducer);
6470d48072f6047140119ff194c1194ce402fca2c0bRobert Carr}
6480d48072f6047140119ff194c1194ce402fca2c0bRobert Carr
6490d48072f6047140119ff194c1194ce402fca2c0bRobert Carrbool SurfaceFlinger::authenticateSurfaceTextureLocked(
6500d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        const sp<IGraphicBufferProducer>& bufferProducer) const {
651097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
6526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
653134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
654134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
6556b376713907086c9642e7b7e66e51ddfa531b003Brian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps(
6566b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        std::vector<FrameEvent>* outSupported) const {
6576b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    *outSupported = {
6586b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::REQUESTED_PRESENT,
6596b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::ACQUIRE,
6606b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::LATCH,
6616b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::FIRST_REFRESH_START,
6626b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::LAST_REFRESH_START,
6636b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::GPU_COMPOSITION_DONE,
6646b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::DEQUEUE_READY,
6656b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::RELEASE,
6666b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    };
6676b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    if (!getHwComposer().hasCapability(
6686b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            HWC2::Capability::PresentFenceIsNotReliable)) {
6696b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
6706b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
6716b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    return NO_ERROR;
6726b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson}
6736b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
6747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
6757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
67623e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
6777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
6787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
6797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6807aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
6817aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
6827aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
683692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6849e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
685692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6861604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6871604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6881604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6891604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6901604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6911604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6921604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
693c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6948b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6958b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6968b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6978b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6988b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6998b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
7008b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
7018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
7028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
7038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
7048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
7058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
7068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
7078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
7088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
7098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
7108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
7111604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
7127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
7137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
7157f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
7167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
7197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
7217f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
7227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
7237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
7247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
7257f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
7267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
7277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
7287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
7307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
7317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
7327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
7337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
7357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
7378722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
7388722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk            info.orientation = hw->getOrientation();
7397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
7407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
7417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
7427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
7437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
7441604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
7457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
7479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
7487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
7497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
7514b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park        info.appVsyncOffset = vsyncPhaseOffsetNs;
7529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
75391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
75491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
75591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
75691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
75791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
75891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
75991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
76091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
76191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
76291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
76391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
76491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
7659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
7660cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard                sfVsyncPhaseOffsetNs + 1000000;
7677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
7697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
7707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
7728b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
7738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
7747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
7757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
776dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
77789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
77867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
77967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
78067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
78167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
78267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
78367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
78467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
78567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
78667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
78767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
78867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
78967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
7906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
7919f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    if (display == NULL) {
7929f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        ALOGE("%s : display is NULL", __func__);
7939f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        return BAD_VALUE;
7949f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    }
7957d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
7967d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<const DisplayDevice> device(getDisplayDevice(display));
79724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
79824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
79924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
8007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
80124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
8027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
803dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
8046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
8056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
8066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
8076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
8086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
8096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
8116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
8126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
8136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
8146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
8166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
8176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
8186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
8196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
8216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
8226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
8236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
8256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
8266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
8276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
8286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
8296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
8306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
8316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
8326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
8336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
8347306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
8357306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
836784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
8379ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
8387306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
8407306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
8416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
8426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
8436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
8447306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
8456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
8466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
8476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
8486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
8496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
8506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
8516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
8526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
8536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
8546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
8556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
856888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
857c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
85828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
85928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
86028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
86128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
86728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
86828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
86928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
87028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
87128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
87228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
87328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
87428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
87528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
87628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
87728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
87828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
87928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
88128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
88228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
88328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
88528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
88628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
8887d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<const DisplayDevice> device(getDisplayDevice(display));
88928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
89028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
89128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
89228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
89328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
89428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
89528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
89628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
89728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
89828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
89928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
90028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
90128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
90228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
90328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
90428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
90528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
90628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
90728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
90828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
9095d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    ALOGD("Set active color mode: %s (%d), type=%d", decodeColorMode(mode).c_str(), mode,
9105d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter          hw->getDisplayType());
9115d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
91228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
91328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
91428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
91528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
91628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
91728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
91828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
91928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
92028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
92128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
92228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
92328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
92428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
92528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
92628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
92728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
92828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
92928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
93028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
93128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
9325d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGE("Attempt to set invalid active color mode %s (%d) for display %p",
9335d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
93428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
93528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
93628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
93728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
9385d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGE("Attempt to set active color mode %s (%d) for null display %p",
9395d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
94028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
9415d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGW("Attempt to set active color mode %s %d for virtual display",
9425d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode);
94328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
94428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
94528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
94628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
94728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
94828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
94928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
95028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
95128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
95228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
953c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
954d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
955d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
956d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
957d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
958d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
959d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
960d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
961d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
962d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
963d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
964d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
965d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
966c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
967c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
968c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
969c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
9707d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<const DisplayDevice> displayDevice(getDisplayDeviceLocked(display));
971c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
972c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
973c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
974c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
975c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
976c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
977c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
978c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
979c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
980c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
981c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
982c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
983c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
984c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
985c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
986c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
987c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
988c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
989c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
990c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
991c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
992c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
993c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
994c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
995c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
996c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
997ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
998c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
999c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
1000c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
1001c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
1002c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
1003c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
1004c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
1005c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1006c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
1007c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
1008c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
1009c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
1010c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
1011c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
1012c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
1013c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1014c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
1015c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
1016c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
1017c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1018c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
1019c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
1020c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
1021d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
1022d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
1023d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
10248aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
1025bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
1026bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
102899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
103199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
103299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
103399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
103499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
103599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
103799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
103899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
103999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
104299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
104399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
1046c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
104799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
104899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
105099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
1051c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
105299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
105399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
105499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
105599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
105699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
105799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10594f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
10604f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
10614f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
10624f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
106399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1065faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
1066faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1067948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
1068faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1069d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1070d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1071faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
107243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
1073faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1074faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1075948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
1076faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1077faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1078948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
1079948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
1080948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
10810a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
10820a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
1083948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
1084948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1085948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
10869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
10879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
1088faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1089faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
1090faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
1091faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1092faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
1093faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1094d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1095d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1096faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
1097faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1098faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1099faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1100948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1103d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1104d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1108948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1109948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1110948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
11134a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
11144a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
11154a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
11160a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
11174a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
11184a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
11194a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
11203cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
11213cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas                                     nsecs_t timestamp) {
11223cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
11233cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    // Ignore any vsyncs from the non-active hardware composer.
11243cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer != mHwc) {
11253cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        return;
11263cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
11273cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
1128d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1129faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1130d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1131d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1132d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1133d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1134faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1135148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1136d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1137d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1138d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1139d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1140d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1141d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1142148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1143148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
11440a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
1145d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
11460a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    *compositorTiming = mCompositorTiming;
11470a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
11480a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
11497d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::createDefaultDisplayDevice() {
11507d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    const int32_t type = DisplayDevice::DISPLAY_PRIMARY;
11517d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    wp<IBinder> token = mBuiltinDisplays[type];
11525d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
11537d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    // All non-virtual displays are currently considered secure.
11547d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    const bool isSecure = true;
11557d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
11567d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<IGraphicBufferProducer> producer;
11577d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<IGraphicBufferConsumer> consumer;
11587d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    BufferQueue::createBufferQueue(&producer, &consumer);
11595576a555a14edd8c76addce2cee37b9b9ced2c3fStephen Kiazyk
11607d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
116180c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko
11627d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    bool hasWideColorModes = false;
11637d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
11647d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    for (android_color_mode_t colorMode : modes) {
11657d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        switch (colorMode) {
11667d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            case HAL_COLOR_MODE_DISPLAY_P3:
11677d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            case HAL_COLOR_MODE_ADOBE_RGB:
11687d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            case HAL_COLOR_MODE_DCI_P3:
11697d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                hasWideColorModes = true;
11707d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                break;
11717d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            default:
11727d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                break;
117380c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko        }
11747d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    }
11757d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
11767d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                                             token, fbs, producer, mRenderEngine->getEGLConfig(),
11777d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                                             hasWideColorModes && hasWideColorDisplay);
11787d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    mDisplays.add(token, hw);
11797d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
11807d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    if (hasWideColorModes && hasWideColorDisplay) {
11817d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        defaultColorMode = HAL_COLOR_MODE_SRGB;
11827d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    }
11837d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    setActiveColorModeInternal(hw, defaultColorMode);
11847d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk}
11858d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
11867d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) {
11877d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
11888722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk
11897d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    if (composer->isUsingVrComposer()) {
11907d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // We handle initializing the primary display device for the VR
11917d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // window manager hwc explicitly at the time of transition.
11927d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        if (disp != DisplayDevice::DISPLAY_PRIMARY) {
11937d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            ALOGE("External displays are not supported by the vr hardware composer.");
11947d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        }
11957d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        return;
11967d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    }
11977d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
11987d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
11997d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        Mutex::Autolock lock(mStateLock);
12007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
12017d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        createDefaultDisplayDevice();
12029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
12039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
12049e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1205692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
12069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
12079e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1208692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1209692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
12109e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
12119e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
12129e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
12139e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
12143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
12158630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
12168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
12173cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onInvalidateReceived(HWComposer* composer) {
12183cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
12193cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer == mHwc) {
12203cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        repaintEverything();
12213cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    } else {
12223cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // This isn't from our current hardware composer. If it's a callback
12233cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // from the real composer, forward the refresh request to vr
12243cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // flinger. Otherwise ignore it.
12253cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        if (!composer->isUsingVrComposer()) {
12263cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas            mVrFlinger->OnHardwareComposerRefresh();
12273cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        }
12283cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
12293cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas}
12303cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
12319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1232faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
12349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
12358630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
12368630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
123787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::clearHwcLayers(const LayerVector& layers) {
123887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    for (size_t i = 0; i < layers.size(); ++i) {
123987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        layers[i]->clearHwcLayers();
124087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
124187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
124287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12437d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk// Note: it is assumed the caller holds |mStateLock| when this is called
12447d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::resetHwcLocked() {
124587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    disableHardwareVsync(true);
124687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mDrawingState.layersSortedByZ);
124787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mCurrentState.layersSortedByZ);
124887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // Clear the drawing state so that the logic inside of
124987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // handleTransactionLocked will fire. It will determine the delta between
125087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // mCurrentState and mDrawingState and re-apply all changes when we make the
125187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // transition.
125287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDrawingState.displays.clear();
1253da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk    // Release virtual display hwcId during vr mode transition.
1254da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1255da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1256da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk        if (displayDevice->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL) {
1257da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk            displayDevice->disconnect(getHwComposer());
1258da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk        }
1259da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk    }
126087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDisplays.clear();
1261050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    initializeDisplays();
126287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
126387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
1264050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid SurfaceFlinger::updateVrFlinger() {
1265050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!mVrFlinger)
1266050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        return;
1267050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
1268050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
1269209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        return;
1270209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
12717d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
1272050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay && !mVrHwc) {
1273209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        // Construct new HWComposer without holding any locks.
1274209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        mVrHwc = new HWComposer(true);
12757d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
12767d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // Set up the event handlers. This step is neccessary to initialize the internal state of
12777d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // the hardware composer object properly. Our callbacks are designed such that if they are
12787d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // triggered between now and the point where the display is properly re-initialized, they
12797d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        // will not have any effect, so this is safe to do here, before the lock is aquired.
12807d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
1281209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        ALOGV("Vr HWC created");
1282209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
128387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12847d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    Mutex::Autolock _l(mStateLock);
128587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12867d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    if (vrFlingerRequestsDisplay) {
12877d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        resetHwcLocked();
128887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12897d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        mHwc = mVrHwc;
12907d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        mVrFlinger->GrantDisplayOwnership();
129187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12927d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    } else {
12937d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        mVrFlinger->SeizeDisplayOwnership();
129487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12957d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        resetHwcLocked();
12967d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
12977d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        mHwc = mRealHwc;
12987d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk        enableHardwareVsync();
129987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
13007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
13017d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    mVisibleRegionsDirty = true;
13027d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    invalidateHwcGeometry();
13037d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
13047d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    // Explicitly re-initialize the primary display. This is because some other
13057d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    // parts of this class rely on the primary display always being available.
13067d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    createDefaultDisplayDevice();
13077d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
13087d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    android_atomic_or(1, &mRepaintEverything);
13097d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    setTransactionFlags(eDisplayTransactionNeeded);
131087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
131187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
13124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
13131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
131499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
13156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
13165018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
13175018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
13180a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                    (mPreviousPresentFence->getSignalTime() ==
13190a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                            Fence::SIGNAL_TIME_PENDING);
13205018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1321c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
1322af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                ALOGD("Backpressure trigger, skipping transaction & refresh!");
13235018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
13245018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
13255018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
13265018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
1327050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // Now that we're going to make it to the handleMessageTransaction()
1328050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // call below it's safe to call updateVrFlinger(), which will
1329050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // potentially trigger a display handoff.
1330050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            updateVrFlinger();
1331050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
13326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
13336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
13345878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
13356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
13365878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
13375878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
13385878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
13396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
13406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
13416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
13426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13436b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
13446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
13456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
13466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13506b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1351c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard    uint32_t transactionFlags = peekTransactionFlags();
13524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
135387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
13546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
13554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13566b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
13574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13596b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1360cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
13616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
13624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
13633a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
13644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
136614cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
136740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
136805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
1369d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    preComposition(refreshStartTime);
137005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
137105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
137205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
137305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
13740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    postComposition(refreshStartTime);
137505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
137611d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
1377bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1378bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1379bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1380bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1381bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1382bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1383bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
138414cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
13859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1386cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1387cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1388cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1389cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1390cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1391cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1392cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1393cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1394cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1395cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1396cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
13972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1398cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1399cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1400cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1401cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1402cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1403cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1404cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1405cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
14063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
14073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
14083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1410cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1411cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1412cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1413cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1414cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1415cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1416cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1417cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1418cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1419bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14217bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
14227bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14237bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14247bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14257bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
14267bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
14279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
14289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1429bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1430cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1431cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1432d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
1433cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
14349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
14359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
14369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1437cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
14382047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
14392047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        if (layer->onPreComposition(refreshStartTime)) {
1440cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1441cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
14422047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
14432047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
1444cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1445cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1446cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1447cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1448a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
14490a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::updateCompositorTiming(
14500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
14510a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        std::shared_ptr<FenceTime>& presentFenceTime) {
14520a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Update queue of past composite+present times and determine the
14530a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // most recently known composite to present latency.
14540a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositePresentTimes.push({compositeTime, presentFenceTime});
14550a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t compositeToPresentLatency = -1;
14560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (!mCompositePresentTimes.empty()) {
14570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        CompositePresentTime& cpt = mCompositePresentTimes.front();
14580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // Cached values should have been updated before calling this method,
14590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // which helps avoid duplicate syscalls.
14600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t displayTime = cpt.display->getCachedSignalTime();
14610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        if (displayTime == Fence::SIGNAL_TIME_PENDING) {
14620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            break;
14630a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        }
14640a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        compositeToPresentLatency = displayTime - cpt.composite;
14650a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
14660a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
14670a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14680a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Don't let mCompositePresentTimes grow unbounded, just in case.
14690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (mCompositePresentTimes.size() > 16) {
14700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
14710a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
14720a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1473d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(
1474d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            vsyncPhase, vsyncInterval, compositeToPresentLatency);
1475d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson}
1476d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
1477d001058145c2186f454a3fb043388d6d9b84c9d8Brian Andersonvoid SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
1478d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
14790a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Integer division and modulo round toward 0 not -inf, so we need to
14800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // treat negative and positive offsets differently.
1481d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
14820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
14830a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
14840a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1485d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
1486d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    if (idealLatency <= 0) {
1487d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        idealLatency = vsyncInterval;
1488d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
1489d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
14900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snap the latency to a value that removes scheduling jitter from the
14910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // composition and present times, which often have >1ms of jitter.
14920a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Reducing jitter is important if an app attempts to extrapolate
14930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // something (such as user input) to an accurate diasplay time.
14940a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
14950a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // with (presentLatency % interval).
1496d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t bias = vsyncInterval / 2;
1497d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    int64_t extraVsyncs =
1498d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
1499d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
1500d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
15010a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1502d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
15030a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.deadline = vsyncPhase - idealLatency;
15040a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.interval = vsyncInterval;
1505d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
15060a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
15070a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15080a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1509cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
15109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
15119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
15129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
15133546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    // Release any buffers which were replaced this frame
1514f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson    nsecs_t dequeueReadyTime = systemTime();
15153546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    for (auto& layer : mLayersWithQueuedFrames) {
1516f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson        layer->releasePendingBuffer(dequeueReadyTime);
15173546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    }
15183546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson
15197d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    // |mStateLock| not needed as we are on the main thread
15207d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
15213d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15223d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
15233d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
15243d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime =
15253d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
15263d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
15273d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
15283d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
15293d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
15303d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mGlCompositionDoneTimeline.updateSignalTimes();
15313d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15324e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
15334e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
15344e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    mDisplayTimeline.push(presentFenceTime);
15353d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.updateSignalTimes();
15363d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15370a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
15380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
15390a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15400a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // We use the refreshStartTime which might be sampled a little later than
15410a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // when we started doing work for this frame, but that should be okay
15420a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // since updateCompositorTiming has snapping logic.
15430a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    updateCompositorTiming(
15444e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
1545d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    CompositorTiming compositorTiming;
1546d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    {
1547d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
1548d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        compositorTiming = mCompositorTiming;
1549d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
15500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15512047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
15522047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
15534e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                presentFenceTime, compositorTiming);
1554e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
15552047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            recordBufferingStats(layer->getName().string(),
15562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    layer->getOccupancyHistory(false));
1557e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
15582047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
15594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15604e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    if (presentFence->isValid()) {
15614e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1562faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1563faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1564948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1565faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1566faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1567faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1568cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    if (!hasSyncFramework) {
15692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1570faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1571faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1572faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1573faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
15744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
15754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
15764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15774e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (presentFenceTime->isValid()) {
15783d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson            mAnimFrameTracker.setActualPresentFence(
15794e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                    std::move(presentFenceTime));
15804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
15814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
15824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
15839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
15849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
15854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
15864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
15874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
15884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1589b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1590b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1591b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1592b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1593b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1594b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1595b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1596b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1597b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1598b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
15990a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
1600b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1601b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1602b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1603b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1604b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1605b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1606b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1607b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1608cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1609cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1610cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
16119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
16129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
16139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1614cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
1615764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1616764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        ATRACE_CALL();
1617764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        mVisibleRegionsDirty = false;
1618764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        invalidateHwcGeometry();
1619ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
1620764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1621764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region opaqueRegion;
1622764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region dirtyRegion;
1623764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Vector<sp<Layer>> layersSortedByZ;
1624764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
1625764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Transform& tr(displayDevice->getTransform());
1626764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Rect bounds(displayDevice->getBounds());
1627764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            if (displayDevice->isDisplayOn()) {
1628764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                computeVisibleRegions(
1629764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        displayDevice->getLayerStack(), dirtyRegion,
1630764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        opaqueRegion);
1631764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey
1632764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                mDrawingState.traverseInZOrder([&](Layer* layer) {
1633764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    if (layer->getLayerStack() == displayDevice->getLayerStack()) {
1634764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        Region drawRegion(tr.transform(
1635764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                layer->visibleNonTransparentRegion));
1636764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        drawRegion.andSelf(bounds);
1637764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        if (!drawRegion.isEmpty()) {
1638764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layersSortedByZ.add(layer);
1639764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        } else {
1640764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // Clear out the HWC layer if this layer was
1641764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // previously visible, but no longer is
1642764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
1643764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                    nullptr);
1644764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        }
164506a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                    } else {
16468226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changes displayDevice->layerStack upon sleep/awake.
16478226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // Here we make sure we delete the HWC layers even if
16488226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changed their layer stack.
164906a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                        layer->setHwcLayer(displayDevice->getHwcDisplayId(),
165006a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                                nullptr);
165187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
1652764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                });
1653764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            }
1654764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
1655764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.set(bounds);
1656764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.subtractSelf(
1657764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    tr.transform(opaqueRegion));
1658764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->dirtyRegion.orSelf(dirtyRegion);
16593b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
16603b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
16623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
16635d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// pickColorMode translates a given dataspace into the best available color mode.
16645d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// Currently only support sRGB and Display-P3.
16655d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) {
16665d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    switch (dataSpace) {
16675d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        // treat Unknown as regular SRGB buffer, since that's what the rest of the
16685d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        // system expects.
16695d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_UNKNOWN:
16705d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_SRGB:
16715d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_V0_SRGB:
16725d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_SRGB;
16735d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16745d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16755d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_DISPLAY_P3:
16765d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_DISPLAY_P3;
16775d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16785d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16795d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        default:
16805d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            // TODO (courtneygo): Do we want to assert an error here?
16815d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            ALOGE("No color mode mapping for %s (%#x)", dataspaceDetails(dataSpace).c_str(),
16825d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                  dataSpace);
16835d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_SRGB;
16845d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    }
16865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter}
16875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16885d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_dataspace SurfaceFlinger::bestTargetDataSpace(android_dataspace a, android_dataspace b) {
16895d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    // Only support sRGB and Display-P3 right now.
16905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) {
16915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3;
16925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    }
16935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    return HAL_DATASPACE_V0_SRGB;
16945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter}
16955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
1696cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
16979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
16989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
16999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1700028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1701b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1702b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1703b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1704b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1705b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1706b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1707b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1708b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1709b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1710b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1711b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1712b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1713b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1714b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1715b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1716b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1717b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1718b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1719b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1720b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1721b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
17227143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1723b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1724b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1725b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1726b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1727028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1728028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
17299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
17309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
17319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
17329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
17339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
17349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
17359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
17369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
1738ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                for (size_t i = 0; i < currentLayers.size(); i++) {
17391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    const auto& layer = currentLayers[i];
17409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
17419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
17429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
17439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
17449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
17459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
17469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1747a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1748a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1749a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1750ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    layer->setGeometry(displayDevice, i);
17519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
17529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
175303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
175403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
175503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
175603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
17579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
175803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
17599f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
17609f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
17619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
17629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
17639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
17659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
17665d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
17689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
17699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
17709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
17719f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
17729f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
17739f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
17749f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
17759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
177738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
17785d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17795d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        if (hasWideColorDisplay) {
17805d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            android_color_mode newColorMode;
17815d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
17825d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17835d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17845d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace);
17855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
17865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
17875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
17885d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            }
17895d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            newColorMode = pickColorMode(newDataSpace);
17905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            setActiveColorModeInternal(displayDevice, newColorMode);
17925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        }
179352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
17949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
17959f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
17969f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
17979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
17997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
18007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
18017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
18027bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
18037bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
18049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
18059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
18069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
180852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1809cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1810cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
18119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
18129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
181352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
181492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
18154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
18162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
181902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
182002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
182102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
182202b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1823cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1824cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
182687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
18274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
182852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1833841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
18349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1835b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1836a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1837a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1838c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
18399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
18409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
18417bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
18427bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
18437bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
18449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
18459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
1846a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard            mHwc->presentAndGetReleaseFences(hwcId);
18479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
18482dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1849b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
18509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
18519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
18529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
18539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
18549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
18559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
18569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
185752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
18589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
18599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
18609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
18619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1862ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1863e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1864e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1865a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1866a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
18676547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
18687d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    // |mStateLock| not needed as we are on the main thread
18697d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
18706547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
18716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
18726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1877841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1878841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
18797cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
18807cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
18817cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
18827cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
18837cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
18847cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1885ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1886ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1887ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1888ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1889ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1890ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1891ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1892ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1893ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
189687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1897ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1898ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1899ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1900ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1901ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
19023d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
19053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
19067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
19072047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([](Layer* layer) {
19082047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        layer->notifyAvailableFrames();
19092047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
19107dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
19172047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
19192047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (!trFlags) return;
1920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
19242047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
19283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1931e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
193292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
193392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
193492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1935e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1936e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
193792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
193992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
194093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
194192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
194292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
194392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
194492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
194592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
194692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1947e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1948e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
194992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
19503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
195127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
195227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
195327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
19547d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
1955875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
19567d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                        sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
195702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
195802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
19599e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
19607adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
196102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
196292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
196392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
196492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
196592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
196692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1967e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
19683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1969097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1970097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
19711474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1972e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
197393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
197493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
197593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
19767d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                        sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
197702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
197802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
197993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
198093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
198193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
198293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
198393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
198492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
198593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
19867d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                    const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));
198793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
198893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
198993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
199093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
199100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
199200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
199300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
199400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
199500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
19964fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
199793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
199847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
199947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
200047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
200192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
200292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
200392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
200492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
200592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
200692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
200792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
2008e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
2009e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
2010cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
201199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
2012db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
2013b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
2014b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
20150556d79eacbf0c9978080d87aa4075120533c7efMathias Agopian                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
2016db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
20179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
201899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
201902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
202002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
202102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
202299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
2023db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
20245cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk                            // Allow VR composer to use virtual displays.
20255cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk                            if (mUseHwcVirtualDisplays || mHwc == mVrHwc) {
20268cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int width = 0;
20278cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int status = state.surface->query(
20288cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
20298cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20308cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query width (%d)", status);
20318cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int height = 0;
20328cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
20338cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
20348cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20358cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query height (%d)", status);
20368cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int intFormat = 0;
20378cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
20388cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
20398cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20408cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query format (%d)", status);
20418cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                auto format = static_cast<android_pixel_format_t>(
20428cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        intFormat);
20438cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
20448cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
20458cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        &hwcId);
20468cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            }
20479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20485cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
20495cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
20509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
20519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
20529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
20539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
2054db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
2055db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
205647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
205799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
205899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
2059cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
2060cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
2061cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
2062cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
206387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
206487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        hwcId = state.type;
206587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
206687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        producer = bqProducer;
2067cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
2068cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
2069cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
207099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
20715d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                        sp<DisplayDevice> hw =
20725d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
20735d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  dispSurface, producer,
20745d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  mRenderEngine->getEGLConfig(),
20755d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  hasWideColorDisplay);
2076cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
2077cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
20784fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
20798dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
2080cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
20819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
20827adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
20831c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
208493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
208592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
208692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
20883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
20918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
20928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
20938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
20948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
20958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
20968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
20978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
20988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
20998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
21008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
21018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
21038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
21048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
21068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
21078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
21088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
21098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
21118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
21122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool first = true;
21132047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
21148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
21158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
21168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
21171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            uint32_t layerStack = layer->getLayerStack();
21182047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (first || currentlayerStack != layerStack) {
21198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
21208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
21218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
21228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
21238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
21248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
21258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
21268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
21278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
21288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
21298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
213091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
21318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
21328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
21338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
21348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
21358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
213691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
213791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
213891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
213991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
214091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
214191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
214291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
21437d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk                disp = getDefaultDisplayDeviceLocked();
21448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
214591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
21462047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
21472047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            first = false;
21482047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
21498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
21508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
21518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
21523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
21533559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
21543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
21551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
21561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (mLayersAdded) {
21571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = false;
21581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        // Layers have been added.
21593559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
21603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
21613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
21623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
21633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
21643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
21653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
21663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
21672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
21681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
21693559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
21703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
21713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
21723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
21731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                Region visibleReg;
21741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                visibleReg.set(layer->computeScreenBounds());
21751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                invalidateLayerStack(layer->getLayerStack(), visibleReg);
21760aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
21772047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
2178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
218103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
218203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
218303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
218403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
218503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
218603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
21879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
21889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
21899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
219003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
219103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
21929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
21939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
21949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
219503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
219603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
21974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
21984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
21994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
22004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
2201598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
22024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
22031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& l : mLayersPendingRemoval) {
22041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            recordBufferingStats(l->getName().string(),
22051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    l->getOccupancyHistory(true));
22061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            l->onRemoved();
22074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
22084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
22094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
22104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
22114b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
22124b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
22134b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
22144b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
22154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
22161f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mDrawingState.traverseInZOrder([](Layer* layer) {
22171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->commitChildList();
22181f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    });
22192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
22202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
22214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
2222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22242047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
222587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
2226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2227841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
22289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
2229841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
2230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
2231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
2233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22362047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
22381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
22411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != layerStack)
22422047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            return;
224387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2244ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2245ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
2246ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
2248ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2249ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2250ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
2251ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
2252ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
2253ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
2254ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
2256ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2257ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2258ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
2259ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
2260ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
2262ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2263a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
2264a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
2265a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
2266a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
2267a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
2268a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
2269a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
2270a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
2271a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
2272a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
2273ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2274ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
2275da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
22764125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
22771f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Rect bounds(layer->computeScreenBounds());
2278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
22791f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Transform tr = layer->getTransform();
2280ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
2281ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
2282ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
228322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
228422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
228522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
22864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
228722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
228822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
228922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
22904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
2291ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2293ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
22941f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                const int32_t layerOrientation = tr.getOrientation();
22959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
2296ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
2297ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
2298ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
2299ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2303ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
2304ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
2305ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2306ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
2307ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
2308ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
2313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
2314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
2315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
23174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
2320a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
2321ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
2322ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
2323ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
2324ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2325ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
2326ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
2327ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
2328ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2329ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
2330ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
2331a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
2332ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
23334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
23344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
2335ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
2336ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
2339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
234187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
2342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2343ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
2344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
23458b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2346a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
2347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
2348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
2349a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
2350a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
23512047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
2352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
2354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
235787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
235892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
23594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
23604297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
23614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
236292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
236392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
236487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
236587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
23666b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
23699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2370d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    nsecs_t latchTime = systemTime();
237199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
23724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
23736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
23740cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan    bool newDataLatched = false;
237551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
237651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
237751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
237851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
237951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
238051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
238151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
238251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
238351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
238451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
23852047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
23866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
23876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
23886b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
23892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mLayersWithQueuedFrames.push_back(layer);
2390ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2391ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
23926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2393ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2394ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
23956b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
23962047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
23972047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
23989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
2399d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
2400ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
24011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        invalidateLayerStack(layer->getLayerStack(), dirty);
24020cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan        if (!dirty.isEmpty()) {
24030cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan            newDataLatched = true;
24040cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan        }
24054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
24064da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
24073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
24086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
24106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
24116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
24129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
24136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
24146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
24156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
24170cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan    return !mLayersWithQueuedFrames.empty() && newDataLatched;
2418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2420ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2421ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
24229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2423ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2424ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
242599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2426830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition(
2427830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        const sp<const DisplayDevice>& displayDevice,
242887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24307143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
24317143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
24327143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
24337143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
2434830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
24357143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
24369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
24377143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
24387143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
24397143316af216fa92c31a60d4407b707637382da1Dan Stoza
24409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
24419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
244287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
244387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2444b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
2445830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2447830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    uint32_t flags = displayDevice->getFlags();
24480f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
244929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
245029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
245129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
2452830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        dirtyRegion.set(displayDevice->swapRegion.bounds());
2453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
24540f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
245529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2456df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
245795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
24580f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
2459830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->swapRegion.bounds());
2460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
246129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
2462830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->bounds());
2463830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            displayDevice->swapRegion = dirtyRegion;
2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2467830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
2468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24699c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
2470830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2471da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2472da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2473830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapBuffers(getHwComposer());
2474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
24779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
24809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
24819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
24829f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
24839f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
24849f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
24859f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
24869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
24879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
24889f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
24899f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
24909f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
24919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
24929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
24939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2494a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
24955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#ifdef USE_HWC2
24965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        mRenderEngine->setColorMode(displayDevice->getActiveColorMode());
24975d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        mRenderEngine->setWideColor(displayDevice->getWideColorSupport());
24985d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#endif
24999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2500c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
25019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
25023f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
25037d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk
25047d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            // |mStateLock| not needed as we are on the main thread
25057d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
25063f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
25073f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
25083f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2509c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2510a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2511a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
25129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
25139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2514b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2515b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2516b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
25173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2518b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
25199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2520b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2521766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
25229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2523766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2524766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2525766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2526766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
25279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2528766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2529766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
25309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2531766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2532766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2533766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2534766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2535b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
253687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2537b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
25389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2540a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2541f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
25429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2543766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2544f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2545f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
25469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
25479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2548f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2549f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2550f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2551f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
25523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2553f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
25549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
25559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
25563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2557f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2558f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
255985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
25604b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
256185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
256285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
256385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
25644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
25659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
25669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
25679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
256885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
25699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
25709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
25719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
25729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
25739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
25749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
25759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
257685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
25779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
25789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
25799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
2580267ab79b22f9d0b995ff787e36aca9c39497c489Gray Huang                    case HWC2::Composition::Sideband:
25819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2582ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
25839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
25849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
25859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2586cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2587cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
25881748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard                            layer->clearWithOpenGL(displayDevice);
2589cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
259085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
259185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
25929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
25939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
259485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2595a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
25969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2597da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2598cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
25999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
26009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2601a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
26029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
260385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
260485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
260585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
26069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
260785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
26089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
260985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
26109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
261185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
26124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
26134b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2614f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
26159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
26169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
26179f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
26189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2619f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
26209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
26213f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2624830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
2625830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    const int32_t height = displayDevice->getHeight();
26263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
26273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26307d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2631ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
26326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
26331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& lbc,
26341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& parent)
26351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
26367d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
26377d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
26387d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
26391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (mNumLayers >= MAX_LAYERS) {
26407d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
26417d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
26421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (parent == nullptr) {
26431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            mCurrentState.layersSortedByZ.add(lbc);
26441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        } else {
26451f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            parent->addChild(lbc);
26461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
26477d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
26481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = true;
26491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mNumLayers++;
26507d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
26517d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
265296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2653ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
26544f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
26557d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
265696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
265796f0819f81293076e652792794a961543e6750d7Mathias Agopian
26589524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carrstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
26597f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr    Mutex::Autolock _l(mStateLock);
26607f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr
26611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const auto& p = layer->getParent();
26621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
26631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.layersSortedByZ.remove(layer);
26641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
2665136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // As a matter of normal operation, the LayerCleaner will produce a second
2666136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // attempt to remove the surface. The Layer will be kept alive in mDrawingState
2667136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // so we will succeed in promoting it, but it's already been removed
2668136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // from mCurrentState. As long as we can find it in mDrawingState we have no problem
2669136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // otherwise something has gone wrong and we are leaking the layer.
2670136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) {
26711f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        ALOGE("Failed to find layer (%s) in layer parent (%s).",
26721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->getName().string(),
26731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (p != nullptr) ? p->getName().string() : "no-parent");
26741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        return BAD_VALUE;
2675136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    } else if (index < 0) {
2676136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr        return NO_ERROR;
2677598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
26781f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
26791f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersPendingRemoval.add(layer);
26801f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersRemoved = true;
26811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mNumLayers--;
26821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    setTransactionFlags(eTransactionNeeded);
26831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    return NO_ERROR;
2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2686c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() {
2687dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2688dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2689dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
26903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
269799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27028b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
27038b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
27048b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
27058b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
27068b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
27077c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2708698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
270928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2710e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
27112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
27122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
27132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
27142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
27157c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
27162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
27172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
27187c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
27197c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
27207c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
27212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
27222d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
27232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
27242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
27252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
27262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2727e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2728e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2729e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2730e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2731b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2732b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2733e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2734698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2735698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2736d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2737d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2738d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2739d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2740d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2741d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2742d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2743d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2744097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2745d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
27462ae83f4f628d4da96f363d0668380ba1f753b867Fabien Sanglard                if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
2747d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2748d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2749d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2750d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2751d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2752698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2753386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
27542a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
27552a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
27562a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
27572a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
27582a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
27592a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
27602a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
276128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2762ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2763ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2764ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2765468051e20be19130572231266db306396a56402bIrvel
2766386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
276728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2768698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2769386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2770386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2771386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
27722d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
27732d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
27742d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
27752d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2776386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
27772d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2778386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2779386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2780386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2781386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
27822d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
27832d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2784386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2785386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2786cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2790e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2791e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
27929a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
27939a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
27949a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
27959a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2796e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
27979a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
27983ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2799e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2800e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2801097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2802e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2803e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2804e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2805e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2809e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2810e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2811e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
281200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2814e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
282647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
282747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
282847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
282947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
283047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
283147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
283247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
283347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
283447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
283547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
284513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
284899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
284999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
285199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2852e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
285382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
28571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            const auto& p = layer->getParent();
28581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (p == nullptr) {
28591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
28601f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (layer->setLayer(s.z) && idx >= 0) {
28611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.removeAt(idx);
28621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.add(layer);
28631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // we need traversal (state changed)
28641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // AND transaction (list changed)
28651f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
28661f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
28671f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else {
28681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (p->setChildLayer(layer, s.z)) {
28691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
28701f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
2871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2873db66e627ad8904491e384c64f82fc77a939b9705Robert Carr        if (what & layer_state_t::eRelativeLayerChanged) {
2874db66e627ad8904491e384c64f82fc77a939b9705Robert Carr            if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) {
2875db66e627ad8904491e384c64f82fc77a939b9705Robert Carr                flags |= eTransactionNeeded|eTraversalNeeded;
2876db66e627ad8904491e384c64f82fc77a939b9705Robert Carr            }
2877db66e627ad8904491e384c64f82fc77a939b9705Robert Carr        }
2878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
28849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2895231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
290099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2903acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
29048d5227b8416b099c884429312daf2d60496fa484Robert Carr            if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize))
2905acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2906acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
29091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // We only allow setting layer stacks for top level layers,
29101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // everything else inherits layer stack from its parent.
29111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->hasParent()) {
29121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
29131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        layer->getName().string());
29141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (idx < 0) {
29151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer without parent (%s) that "
29161f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        "that also does not appear in the top level layer list. Something"
29171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        " has gone wrong.", layer->getName().string());
29181f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (layer->setLayerStack(s.layerStack)) {
2919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2922e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2923e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2925e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
29267dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
29270d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            if (s.barrierHandle != nullptr) {
29280d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
29290d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            } else if (s.barrierGbp != nullptr) {
29300d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
29310d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                if (authenticateSurfaceTextureLocked(gbp)) {
29320d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    const auto& otherLayer =
29330d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
29340d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
29350d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                } else {
29360d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    ALOGE("Attempt to defer transaction to to an"
29370d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                            " unrecognized GraphicBufferProducer");
29380d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                }
29390d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            }
29407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
29417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
29427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
29431db73f66624e7d151710483dd58e03eed672f064Robert Carr        if (what & layer_state_t::eReparentChildren) {
29441db73f66624e7d151710483dd58e03eed672f064Robert Carr            if (layer->reparentChildren(s.reparentHandle)) {
29451db73f66624e7d151710483dd58e03eed672f064Robert Carr                flags |= eTransactionNeeded|eTraversalNeeded;
29461db73f66624e7d151710483dd58e03eed672f064Robert Carr            }
29471db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
29489524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        if (what & layer_state_t::eDetachChildren) {
29499524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr            layer->detachChildren();
29509524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        }
2951c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2952c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2953c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2954c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2955c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2959e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
29604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
29610ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
29620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
29634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
2964479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
2965479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
2966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29676e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2968921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
29696e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
29704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
29716e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
29728b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
29734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
29744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
29754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
29764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2977bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    String8 uniqueName = getUniqueLayerName(name);
2978bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
29793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
29803165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
29814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
2982bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                    uniqueName, w, h, flags, format,
29834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
29853165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
29864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
2987bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                    uniqueName, w, h, flags,
29884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
29894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
29904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
29914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
29967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
29987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
2999479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk    layer->setInfo(windowType, ownerUid);
3000479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk
30011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result = addClientLayer(client, *handle, *gbp, layer, *parent);
30027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
30037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
30047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
3005ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
30067d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
30077d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
30084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
3009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3011bc7552874052ee33f1b35b4474e20c003d216391Cody NorthropString8 SurfaceFlinger::getUniqueLayerName(const String8& name)
3012bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop{
3013bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    bool matchFound = true;
3014bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    uint32_t dupeCounter = 0;
3015bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3016bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    // Tack on our counter whether there is a hit or not, so everyone gets a tag
3017bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str());
3018bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3019bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    // Loop over layers until we're sure there is no matching name
3020bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    while (matchFound) {
3021bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        matchFound = false;
3022bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        mDrawingState.traverseInZOrder([&](Layer* layer) {
3023bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop            if (layer->getName() == uniqueName) {
3024bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                matchFound = true;
3025bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str());
3026bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop            }
3027bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        });
3028bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    }
3029bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3030bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    ALOGD_IF(dupeCounter > 0, "duplicate layer name: changing %s to %s", name.c_str(), uniqueName.c_str());
3031bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3032bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    return uniqueName;
3033bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop}
3034bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
30354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
30364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
30374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
3038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
304092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
3041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
3042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
3043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
3044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
3045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
30468f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
3047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
3048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
30514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
30524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
30534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
3054b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
3055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
30564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
30574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
30584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
3059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
30624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
30634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
3064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
30664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
3067b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
30684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
3069118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3070118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3071ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
30729a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
30739524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    // called by a client when it wants to remove a Layer
30746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
30756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
30766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
3077ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
30786710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
30796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
30806710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
30819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
30829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
30839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
30849a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
308513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
3086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30876710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
30886710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
30899524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    sp<Layer> l = layer.promote();
30909524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    if (l == nullptr) {
30919524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // The layer has already been removed, carry on
30929524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
30939524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    } if (l->getParent() != nullptr) {
30949524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // If we have a parent, then we can continue to live as long as it does.
30959524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
30969524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    }
30979524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    return removeLayer(l);
3098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3100b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
3101b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
310213a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
310301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
310413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
310513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
310613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
310701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
310801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
3109692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
311001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
311113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
31124c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
31134c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
311447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
311547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
311613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
311713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
31182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
31196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
31209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
31219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
31226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
31230a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
3124d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use phase of 0 since phase is not known.
3125d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use latency of 0, which will snap to the ideal latency.
3126d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(0, period, 0);
312713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
312813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
312913a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
313013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
313113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
313213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
3133c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
313413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
313513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
313613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
313713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
313813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
313913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
314013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
314113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
314213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
31432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
31442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
31452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
31462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
31472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
31482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
314913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
31502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
3151c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
3152c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
3153c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
31542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
31552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
31562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
31572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
31582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
3159c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
3160ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
3161ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
3162ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
3163ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
3164ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
3165ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
3166ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
3167ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
3168ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
3169ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
31702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
3171f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
31722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3173c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3174c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
3175c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
3176948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
3177c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
3178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
3180b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
31812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
3182f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3183f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3184f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
3185f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
3186f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
3187f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
31882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
3189f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
3190f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3191f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
3192f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
3193f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
3194f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3195c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3196948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
3197948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
3198cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
3199cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
3200cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
3201c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
32022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
32032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
32042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
32052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
32062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3207b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
3208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
32112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
3212db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
3213db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
32142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
3215b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
32162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
32172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
32182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
3219b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
32202c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
3221db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
32222c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
32237306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
32249e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
32252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
32262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
3227db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
32282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
3229db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
3230b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
3231b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
3232b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
32332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
3234db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
3235b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
3236b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3237b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
3238b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
3240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
324299b49840d309727678b77403d6cc9f920111623fMathias Agopian
3243bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
3244bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
3245bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
3246bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
3247bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
324874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
3249bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
3250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
3251fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
32529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
32539795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
3254fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
3255fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
32569795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
3257fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
3258fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
3259fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
32609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
32619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
326282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
326382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
326425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
326525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
326625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
326725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
326825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
326974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
327035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
327125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
327225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
327325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
327425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
327582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
327674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
327735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
327882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
327925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
328025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
328125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
328225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
328374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
328435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
328525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
3286c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
3287c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
3288c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
3289c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
3290c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
3291c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
3292c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
3293b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3294b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
3295b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
3296b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
3297b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
3298b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
3299b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
330040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
330140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
3302d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    (args[index] == String16("--frame-events"))) {
330340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
3304d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                dumpFrameEventsLocked(result);
330540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
330640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
3307f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3308f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            if ((index < numArgs) && (args[index] == String16("--wide-color"))) {
3309f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                index++;
3310f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                dumpWideColorInfo(result);
3311f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                dumpAll = false;
3312f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            }
3313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
33141b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
331582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
331674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
331782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
331848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
331982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
332082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
332148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
332282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
332382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
332482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
332582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
332648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
3327c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
3328c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
332925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
33302047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
333174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
33322047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
333325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
333425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
333582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
333674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
333782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
333882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
333982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
334082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
334182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
334282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
334348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
33449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
33459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
334686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
33474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
33484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
3349d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
33504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
33512047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
33524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
3353d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
33544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
33552047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
335682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
335782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
3358ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
335925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
3360c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
336125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
336225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
336325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
336425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
336525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
336625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
336725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
33682047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
336925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
3370d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
337125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
33722047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
33734b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
3374d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
337525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
337625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
33776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
33786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
33796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
33802047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
33816547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
33822047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
33836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
33846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
33856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
33866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
338763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const
33884803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
338963a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" [sf");
3390c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    result.appendFormat(" HAS_CONTEXT_PRIORITY=%d", useContextPriority);
3391c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
339263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    if (isLayerTripleBufferingDisabled())
339363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard        result.append(" DISABLE_TRIPLE_BUFFERING");
3394c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
3395c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset);
3396a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
3397c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
3398cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
33991971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
34001971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard                        maxFrameBufferAcquiredBuffers);
340163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append("]");
34024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
34034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
3404b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
3405b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
3406b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
3407b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
3408b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
3409b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
3410b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
3411b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
3412b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
3413b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
3414b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
3415b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
3416b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
3417b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
3418b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
3419b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
3420b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3421e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
3422e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
3423e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3424e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
3425e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
3426e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
3427e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
3428e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3429e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
3430e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
3431e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
3432e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
3433e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3434e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
3435e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
3436e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3437e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3438e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3439d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
3440d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("Layer frame timestamps:\n");
3441d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3442d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
3443d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const size_t count = currentLayers.size();
3444d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    for (size_t i=0 ; i<count ; i++) {
3445d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        currentLayers[i]->dumpFrameEvents(result);
3446d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
3447d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
3448d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3449e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
3450e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
3451e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
3452e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
3453e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3454e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
3455e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
3456e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
3457e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
3458e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
3459e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
3460e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
3461e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3462e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
3463e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
3464e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
3465e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
3466e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
3467e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
3468e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
3469e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
3470e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3471e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3472e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3473e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3474e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3475e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3476e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3477e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3478e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3479e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3480e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3481e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3482e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3483f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchtervoid SurfaceFlinger::dumpWideColorInfo(String8& result) const {
3484f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
3485f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3486f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    // TODO: print out if wide-color mode is active or not
3487f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3488f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    for (size_t d = 0; d < mDisplays.size(); d++) {
3489f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3490f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        int32_t hwcId = displayDevice->getHwcDisplayId();
3491f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3492f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            continue;
3493f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        }
3494f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3495f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        result.appendFormat("Display %d color modes:\n", hwcId);
3496f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(hwcId);
3497f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        for (auto&& mode : modes) {
3498f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            result.appendFormat("    %s (%d)\n", decodeColorMode(mode).c_str(), mode);
3499f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        }
3500f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3501f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        android_color_mode_t currentMode = displayDevice->getActiveColorMode();
3502f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        result.appendFormat("    Current color mode: %s (%d)\n",
3503f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                            decodeColorMode(currentMode).c_str(), currentMode);
3504f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    }
3505f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.append("\n");
3506f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter}
3507f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
350874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
350974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
351082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
35113e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
35123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
35133e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
35143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
35153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
35163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
35173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
35183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
35193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
352082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
352182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
352282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
352382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
352482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
352582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3526bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
352782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
35284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
35294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
35303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
35313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
35324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
35333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
35354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
35364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
35374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
35384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
3539f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.append("\nWide-Color information:\n");
3540f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    dumpWideColorInfo(result);
3541f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
35423e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3543ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
35443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3545ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3546ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3547ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
35489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
35499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
355041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
355141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
355241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
355324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
3554c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
35559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
3556c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard        dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
355741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
355841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3559b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3560b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3561b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3562b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3563b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3564e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3565e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
35664803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
356782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
356882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
35693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
35701f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
35713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35722047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
35733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
35742047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3575bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
357682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
35775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
35785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
35795f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
35803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
358186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
35823e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
35845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
358574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
35865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
35875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
35885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
358982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
359082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
35911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
35923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
359374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
35943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3596888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
35977d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
3598ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
35993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
36003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
36013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
36023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
36033e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3604ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3605ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3606875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
36079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
36084297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
36092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
36102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
361174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
361282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
361382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3614c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
361582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
361682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3617ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3618ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3619ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
362082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
362182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3622c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
36239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
36249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
36259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3626ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
362782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
362874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
362982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
363082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
363174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
363282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
363382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
363482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
363582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
363682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
363774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3638e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3639e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3640e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3641e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3642e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3643e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3644e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3645e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3646e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3647e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3648e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3649e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3650e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3651e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
36521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
3653e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
36541f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
3655e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3656e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
365782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
365882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
365982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
366082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
36613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
366274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
36633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
36649f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
36659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
36669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
366774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
366882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
366982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
367082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
367182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
367282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
367382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
367613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
367748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3678db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
367948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
368048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
368148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
368248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
368348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
368448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
368548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
368648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
368748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
368848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
368948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
369048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
36917d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk    return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ();
3692cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3693cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
369463f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
369563f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
369663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
369763f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
369863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
369963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
370063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
370163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
370263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
370324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
370463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
370563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
370663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
370763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
370863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
370963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
371063f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
371163f165fd6b86d04be94d4023e845e98560504a96Keun young Park
37126e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3715041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3717d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3718d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
37192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3720c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3725a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
37263bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
372799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
37286e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3729375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
37311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
37321b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
37331db73f66624e7d151710483dd58e03eed672f064Robert Carr        /*
37341db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Calling setTransactionState is safe, because you need to have been
37351db73f66624e7d151710483dd58e03eed672f064Robert Carr         * granted a reference to Client* and Handle* to do anything with it.
37361db73f66624e7d151710483dd58e03eed672f064Robert Carr         *
37371db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
37381db73f66624e7d151710483dd58e03eed672f064Robert Carr         */
37391db73f66624e7d151710483dd58e03eed672f064Robert Carr        case SET_TRANSACTION_STATE:
37401db73f66624e7d151710483dd58e03eed672f064Robert Carr        case CREATE_SCOPED_CONNECTION:
37411db73f66624e7d151710483dd58e03eed672f064Robert Carr        {
37421db73f66624e7d151710483dd58e03eed672f064Robert Carr            return OK;
37431db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
37441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
37451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
37461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
37471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
37481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
37491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
375099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
375199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
37526e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
37531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
37541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
37551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
37586e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
37596e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
37606e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
37616e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
37626e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
37636e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
37646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
37656e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
37666e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
37676e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
37681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3771b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
377299ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3773375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3774375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3775375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3776e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3777375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
378201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
378335b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
378853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
378953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
379253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3795cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3796e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3797e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3798e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3799e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3800cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
38024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
38034d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
38044d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
38054d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
380653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
380753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
380853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
380953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
381053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
381153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3812a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3813a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3814a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3815a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3816a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3817a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
381901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3822b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
382312839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
38268722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
38274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3828ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3829ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3830ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3831ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3832ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3833ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
38349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
38359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
38369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
38389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
38399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
38419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
38429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
38449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
38459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3846ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3847ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
38489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3849ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
38509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3851ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3852ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3853ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
38549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
38559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
38569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
38579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
38589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
38599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
38609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
38619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
38629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3863794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
38649f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
38659f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
38669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
38679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
38689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
38699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
38709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
38719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
38729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
38739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3875f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3876f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3877f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3878645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3879645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3880f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3881f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3882ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3883ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3884ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3885ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3886ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3887db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3888db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3889db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3890db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3891db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3892db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3893db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3894db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3895db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3896db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3897468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3898468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3899468051e20be19130572231266db306396a56402bIrvel                if (n) {
3900468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3901ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3902468051e20be19130572231266db306396a56402bIrvel                }
3903468051e20be19130572231266db306396a56402bIrvel                else{
3904468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3905468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3906468051e20be19130572231266db306396a56402bIrvel                }
3907468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3908468051e20be19130572231266db306396a56402bIrvel            }
39098cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
39108cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
39118cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
39128cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
39138cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
391953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
392087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
392199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
392253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
392353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
392459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
39252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
39262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
392759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
39282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
39292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
39302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3931b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3933b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3934b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
39352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
39362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3937b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3938b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3939b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3940b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3941b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3942b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3943b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3946b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3947b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3948b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3949b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3950b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
39512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
39522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
39532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
39542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
39552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3956b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
39572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
39582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
39592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
39602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
39622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
39632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
39642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
39652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3967b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3968b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3969b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
39702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
39712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3972c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
39732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
39742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
39752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
39762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3977b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3978b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3979b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3980b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
39812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
39822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
39832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3984b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3985b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3986b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
39872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
39882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
39892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3990c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
39912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
39922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3994b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
39952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
39962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
39972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3998b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3999b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
4000b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
4001b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
4002097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
40032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
4004b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
40052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
40062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
40072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
4010c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
4011b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
4012b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
401353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
4014b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
401553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
401653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
401753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
401853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
4019b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
4020b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
4021b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
40222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
40232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
40242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
40252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
40262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
40272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
4029b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
40302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
4031aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
40322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
4033b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
4034b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
4035b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
40362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
40372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
40392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
40422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
4043c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4044ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4045c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
40462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
40482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
40492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
40512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
40522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
40545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
40555ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
4056b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
40575ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
4058c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
4059c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
4060c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
4061c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
4062c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
4063c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4064c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
4065c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
4066c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4067c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
4068c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
4069c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4070c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
4071c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
4072c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4073c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
4074c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
4075c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
4076c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4077c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
4078c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
40792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
40802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
40812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
40822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
4083c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
40842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
40852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
4086c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
4087c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
40882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
4089b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
40902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
40912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
40922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
40932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
4094c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4095ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                int32_t minLayerZ, int32_t maxLayerZ,
4096b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
4097b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
4098b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
40992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
4100c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
41012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
4102c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
4103b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
4104b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
41052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
41062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
41082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
41092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41102a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
41112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
41127d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk            sp<const DisplayDevice> hw(flinger->getDisplayDeviceLocked(display));
4113c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
4114c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
4115b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
4116097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
41172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
41182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
41202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
41212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
41222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
41232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
41242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
41252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
41262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
41272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
41282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
41292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
4130c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
4131b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
41322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
41332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
41342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
41352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
41362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
41372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
4138118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
4139118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
4140180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4141180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
4142180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
4143c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4144ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4145c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
4146180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
4147180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
41483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
4149180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4150180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
415189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
415289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
415389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
41540e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
4155180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4156c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
4157c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
4158c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
4159c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
4160c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
4161c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4162c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
4163c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
4164c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
4165c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
4166c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4167be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
4168be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
4169c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4170c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
4171c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
4172c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4173be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
4174be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
4175c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4176c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
4177180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
41783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
4179180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4180180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
4181c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
4182c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
41833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
4184180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4185180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
41863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
4187180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
41881f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // We loop through the first level of layers without traversing,
41891f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // as we need to interpret min/max layer Z in the top level Z space.
41901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
41911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != hw->getLayerStack()) {
41921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
41931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
41941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
41951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (state.z < minLayerZ || state.z > maxLayerZ) {
41961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4197180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
4198412903fce3a93f411c85c54375a1851bfb370400Dan Stoza        layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
41991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (!layer->isVisible()) {
42001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                return;
42011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
42021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(true);
42031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            layer->draw(hw, useIdentityTransform);
42041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(false);
42051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
42061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4207180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4208931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
4209180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
4210180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4211180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
42122a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
42132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
42142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
4215c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4216ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4217b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
4218b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
421974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
4220fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
4221fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
4222180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
42233502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
42243502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
42253502416204d9dbd905012ee586d8bd145323809fDan Stoza
42263502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
42273502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
42283502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
4229180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4230180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
4231180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
4232180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
4233180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
4234180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
4235180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4236180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
4237180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
4238180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4239b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
42401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
4241b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
42421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if ((layer->getLayerStack() != hw->getLayerStack()) ||
42431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (state.z < minLayerZ || state.z > maxLayerZ)) {
42441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4245b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
4246412903fce3a93f411c85c54375a1851bfb370400Dan Stoza        layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer *layer) {
42471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
42481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    layer->isSecure());
42491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
42501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4251b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
4252b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
4253b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
4254b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
4255b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
4256b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
42570aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
42580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
425983cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
4260605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
4261605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
4262605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
4263605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
4264605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
4265605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
4266605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
4267605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
42680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
426974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
42705a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
42715a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
42723ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
42733ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
42742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
42750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
42760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
42774ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
42780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
42790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
42802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
42810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
42820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
42830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
42840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
42850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
42860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
42870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
4288866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
42890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
42900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
42910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
42920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
42930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
42943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
42953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
42963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
42973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
42980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
42990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
43000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
43010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
4302c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
4303c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
4304c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
4305d555684cb36dfb959694db76962e570184f98838Mathias Agopian
4306866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
4307866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
4308866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
4309866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
4310866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
4311866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
43129707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
43139707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
4314866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4315866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
4316866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
43172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
4318866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
4319866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
4320866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
4321866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
4322866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
4323866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
43242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
4325866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4326866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
4327866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
4328866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
4329866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
4330866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
4331866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
4332866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
4333866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
4334866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
4335866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
4336866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
4337866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
4338866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
43392d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
4340866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
43412d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
43422d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
4343d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
4344d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
4345d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
4346d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
4347d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
4348d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
4349d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
4350d555684cb36dfb959694db76962e570184f98838Mathias Agopian
43510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
43520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
43530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
4354f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
4355f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
43560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
43570aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
43580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
43590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
43600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
436174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
4362f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
4363f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
4364f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
4365f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
436674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
43670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
43680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
436974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
43700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
437174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
437274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
437374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
437474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
437574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
4376d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
4377ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) {
4378fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
4379d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
4380d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
4381d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
4382fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
4383fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
4384fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
4385fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
4386fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
4387fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
43881f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
43892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        size_t i = 0;
43901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& layer : mDrawingState.layersSortedByZ) {
4391fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
43921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ &&
43931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    state.z <= maxLayerZ) {
4394412903fce3a93f411c85c54375a1851bfb370400Dan Stoza                layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
43951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
43961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            layer->isVisible() ? '+' : '-',
43971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            i, layer->getName().string(), layer->getLayerStack(), state.z,
4398fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
43991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    i++;
44001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                });
44011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
44021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
4403fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
4404ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
4405ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
44061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
44071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
4408412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const {
4409412903fce3a93f411c85c54375a1851bfb370400Dan Stoza    layersSortedByZ.traverseInZOrder(stateSet, visitor);
4410921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4411921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
4412412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const {
4413412903fce3a93f411c85c54375a1851bfb370400Dan Stoza    layersSortedByZ.traverseInReverseZOrder(stateSet, visitor);
4414921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4415921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
4416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
44173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
44203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
44213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
44223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
44243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
44253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
4426