SurfaceFlinger.cpp revision 1971b63aa4d82db37794f19e0eb01feb1826e422
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
40c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
4167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
42c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
46e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
47f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy#include <gui/GraphicBufferAlloc.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
53cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
570a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h>
581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
61ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
68faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
69d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
70d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr#include "LayerVector.h"
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
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;
12299b49840d309727678b77403d6cc9f920111623fMathias Agopian
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1244f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
128076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
1291f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded(false),
13052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
13187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mHwc(nullptr),
13287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRealHwc(nullptr),
13387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mVrHwc(nullptr),
13487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRenderEngine(nullptr),
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1418afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
143a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
148ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
149ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
1500d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        mInterceptor(this),
1514a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
152faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
153948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
154b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
1581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLastSwapTime(0),
159050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mNumLayers(0),
160050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlingerRequestsDisplay(false)
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
162cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    ALOGI("SurfaceFlinger is starting");
1630cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1640cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1650cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
1660cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1670cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1680cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
1690cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
170cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
171cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
173c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    useContextPriority = getBool< ISurfaceFlingerConfigs,
174c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard            &ISurfaceFlingerConfigs::useContextPriority>(false);
175c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
176c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
177c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
178c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
179a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
180a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
181a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard
182c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
183c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
184c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard
185050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    // Vr flinger is only enabled on Daydream ready devices.
186050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    useVrFlinger = getBool< ISurfaceFlingerConfigs,
187050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            &ISurfaceFlingerConfigs::useVrFlinger>(false);
188050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
1891971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
1901971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);
1911971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
195b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
19650210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
197b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
2008afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
2018afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
2028afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
2038afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
20463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
20563f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
20663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
20763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
2088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
209c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
210c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
211c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
212c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
213c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
214c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
2158cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
216642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    property_get("debug.sf.enable_hwc_vds", value, "0");
217642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    mUseHwcVirtualDisplays = atoi(value);
218642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
21963a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard
220c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    property_get("ro.sf.disable_triple_buffer", value, "1");
221c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    mLayerTripleBufferingDisabled = atoi(value);
22263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
22699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
22799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
22899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
22999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
232a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
233a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
234a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
237c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
23899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
23999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
24099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
24213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
24399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
245a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
24699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
24799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2481db73f66624e7d151710483dd58e03eed672f064Robert Carrstatic sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
24996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
25096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
2511db73f66624e7d151710483dd58e03eed672f064Robert Carr        return client;
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2531db73f66624e7d151710483dd58e03eed672f064Robert Carr    return nullptr;
2541db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2551db73f66624e7d151710483dd58e03eed672f064Robert Carr
2561db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
2571db73f66624e7d151710483dd58e03eed672f064Robert Carr    return initClient(new Client(this));
2581db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2591db73f66624e7d151710483dd58e03eed672f064Robert Carr
2601db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
2611db73f66624e7d151710483dd58e03eed672f064Robert Carr        const sp<IGraphicBufferProducer>& gbp) {
2621db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (authenticateSurfaceTexture(gbp) == false) {
2631db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2641db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2651db73f66624e7d151710483dd58e03eed672f064Robert Carr    const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
2661db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (layer == nullptr) {
2671db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2681db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2691db73f66624e7d151710483dd58e03eed672f064Robert Carr
2701db73f66624e7d151710483dd58e03eed672f064Robert Carr   return initClient(new Client(this, layer));
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
274dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
276e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
283e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
285c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
287e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
288e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
290e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
291e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
29353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2948dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
296ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
297e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
299e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3006c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
3016c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
3026c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3036c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
3046c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
3056c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
3066c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3076c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
3086c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3096c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
3106c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
3116c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
3126c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3136c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
314ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
3156c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
3166c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
3176c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
3186c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
319692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
3209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
321692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
322692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
323692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
324692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
32553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
326692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
327ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
328692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
329692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
330e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
3319e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
332e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
333e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
335692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
336e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
338f8b4ca51111cd2e566d1774ac464da859db78976Romain Guysp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
339f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy{
340f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
341f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy    return gba;
342f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy}
343f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
346b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
347b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
348b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
351a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3523330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3531f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3541f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3551f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3561f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3571f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
358921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3591f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3601f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
361050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (mVrFlinger) {
362050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      mVrFlinger->OnBootFinished();
363050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
364050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
3651f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
366a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
367a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
368a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3690a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3700a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3710a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3720a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
376921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
379921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
382921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
383921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
385921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
386921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
387921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
389921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
390921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
391faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
392faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3935167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3944a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3954a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3960a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3970a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3984a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3994a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
406faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
407faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
408faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
409faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
411faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
4124a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
413faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
414faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
415faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
416faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4185167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
420faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
422faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4265167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
428db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
431faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
432db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
438db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
439db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
440db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
441db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
442db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
445db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
446db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
447db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
448db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
449db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
450db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
451db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
452db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
455db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
457db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
458db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
460db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
461db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
462db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4634a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
464db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
465db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
466db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
467db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
468db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
469db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
470db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
471faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
472faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
473faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
474faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
475db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
476faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
477a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4780a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4810a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
482faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
483faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
484faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
485faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
486faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
487faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
488faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4894a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4904a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
491faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
492faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4930a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4945167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4955167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4960a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
497faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
498db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
499db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
500faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
501db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
502db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
503db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
504db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
505faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
506faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
507c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
508c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
509c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
510c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
511c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
512c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
513c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
514c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
515c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
516c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
517c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
518c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
519c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
520c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
521c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
522c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
523c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
524c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
525c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
526c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
527c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
528c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
529c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
530c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
531faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
532a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
533a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
534a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
5354b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park    ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);
5364b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
5379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
5419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
5429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
543692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
5459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
547ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
5489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
550ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
552a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
553acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
55441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
55535520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
55641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
55741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
55841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
55941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
564f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
568050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
569050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        "Starting with vr flinger active is not currently supported.");
5703cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    mRealHwc = new HWComposer(false);
57187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mHwc = mRealHwc;
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
573b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
575875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
576050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (useVrFlinger) {
577050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
578050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            mVrFlingerRequestsDisplay = requestDisplay;
579050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            signalTransaction();
580050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        };
581050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
582050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                                            vrFlingerRequestDisplayCallback);
583050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (!mVrFlinger) {
584050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            ALOGE("Failed to start vrflinger");
585050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        }
586050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
587050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
588875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
589875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
590a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
591da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
592da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
593da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
5959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
596a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
597a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
598d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
599d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
600d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
60192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
60292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
6038630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
60413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
60513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
60613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
6074e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
6084e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
609b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread = new StartBootAnimThread();
610b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->Start() != NO_ERROR) {
611b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Run StartBootAnimThread failed!");
612b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
6153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
6163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
617a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
618b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Start boot animation service by setting a property mailbox
619b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // if property setting thread is already running, Start() will be just a NOP
620b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread->Start();
621b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Wait until property was set
622b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
623b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
624b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
625a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
626a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
627875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
628875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
629a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
630a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
631875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
632875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
633a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
634a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
636d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
637582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
6382adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
639134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
6400d48072f6047140119ff194c1194ce402fca2c0bRobert Carr    return authenticateSurfaceTextureLocked(bufferProducer);
6410d48072f6047140119ff194c1194ce402fca2c0bRobert Carr}
6420d48072f6047140119ff194c1194ce402fca2c0bRobert Carr
6430d48072f6047140119ff194c1194ce402fca2c0bRobert Carrbool SurfaceFlinger::authenticateSurfaceTextureLocked(
6440d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        const sp<IGraphicBufferProducer>& bufferProducer) const {
645097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
6466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
647134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
648134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
65123e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6557aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
6567aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
6577aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
658692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6599e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
660692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6611604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6621604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6641604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6651604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6661604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6671604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
668c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6708b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6718b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6728b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
6758b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
6768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
6778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
6788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
6798b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
6808b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
6818b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
6828b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
6838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
6848b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
6858b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
6861604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
6887f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
6907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
6917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
6939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
6947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
6967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
6977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
6987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
6997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
7007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
7017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
7027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
7037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
7057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
7067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
7077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
7087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
7107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
7127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
7137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
7147f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
7157f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
7167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
7177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
7187f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
7191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
7207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
7237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
7247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
7264b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park        info.appVsyncOffset = vsyncPhaseOffsetNs;
7279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
72891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
72991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
73091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
73191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
73291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
73391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
73491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
73591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
73691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
73791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
73891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
73991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
7409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
7410cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard                sfVsyncPhaseOffsetNs + 1000000;
7427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
7447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
7457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
74628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
7478b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
7488b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
7497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
7507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
751dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
75289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
75367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
75467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
75567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
75667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
75767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
75867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
75967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
76067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
76167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
76267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
76367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
76467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
7656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
7669f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    if (display == NULL) {
7679f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        ALOGE("%s : display is NULL", __func__);
7689f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        return BAD_VALUE;
7699f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    }
77024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
77124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
77224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
77324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
77424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
7757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
776dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
7776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
7786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
7796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
7806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
7816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
7826c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
7846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
7856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
7906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
7946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
7956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
7966c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7976c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
7986c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
7996c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
8006c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
8016c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
8026c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
8036c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
8046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
8056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
8066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
8077306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
8087306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
809784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
8109ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
8117306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
8137306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
8146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
8156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
8166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
8177306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
8186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
8196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
8206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
8216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
8226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
8236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
8246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
8256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
8266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
8276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
8286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
829888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
830c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
85528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
85628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
85728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
85828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
85928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
86028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
86128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
86728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
86828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
86928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
87028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
87128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
87228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
87328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
87428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
87528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
87628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
87728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
87828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
87928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
88128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
88228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
88328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
88428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
88628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
88728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
88828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
89028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
89128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
89228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
89328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
89428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
89528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
89628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
89728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
89828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
89928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
90028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
90128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
90228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
90328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
90428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
90528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
90628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
90728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
90828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
90928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
91028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
91128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
91228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
91328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
91428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
91528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
91628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
91728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
91828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
91928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
92028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
92128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
92228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
92328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
92428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
92528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
926c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
927d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
928d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
929d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
930d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
931d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
932d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
933d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
934d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
935d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
936d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
937d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
938d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
939c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
940c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
941c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
942c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
943c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
944c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
945c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
946c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
947c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
948c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
949c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
950c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
951c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
952c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
953c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
954c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
955c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
956c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
957c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
958c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
959c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
960c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
961c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
962c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
963c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
964c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
965c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
966c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
967c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
968c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
969c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
970ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
971c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
972c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
973c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
974c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
975c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
976c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
977c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
978c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
979c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
980c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
981c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
982c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
983c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
984c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
985c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
986c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
987c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
988c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
989c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
990c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
991c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
992c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
993c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
994d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
995d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
996d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
9978aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
998bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
999bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
100199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
100299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
100399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
100499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
100599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
100699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
100799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
100899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
100999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
101099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
101199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
101299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
101399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
101499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
101599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
101699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
101799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
101899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
1019c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
102099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
102199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
102299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
102399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
1024c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
102599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
102699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
102799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
102899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
102999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
103099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10324f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
10334f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
10344f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
10354f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
103699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1038faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
1039faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1040948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
1041faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1042d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1043d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1044faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
104543601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
1046faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1047faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1048948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
1049faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1050faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1051948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
1052948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
1053948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
10540a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
10550a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
1056948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
1057948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1058948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
1061faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1062faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
1063faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
1064faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1065faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
1066faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1067d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1068d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1069faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
1070faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1071faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1072faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1073948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1074faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1075faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1076d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1077d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1078faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1079faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1080faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1081948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1082948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1083948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1084faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1085faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
10864a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
10874a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
10884a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
10890a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
10904a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
10914a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
10924a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
10933cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
10943cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas                                     nsecs_t timestamp) {
10953cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
10963cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    // Ignore any vsyncs from the non-active hardware composer.
10973cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer != mHwc) {
10983cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        return;
10993cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
11003cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
1101d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1103d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1104d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1105d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1106d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1108148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1109d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1110d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1111d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1112d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1113d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1114d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1115148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1116148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
11170a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
1118d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
11190a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    *compositorTiming = mCompositorTiming;
11200a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
11210a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
11229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
11239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
11249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
11259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
11269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
11289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
11299e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
11309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
113187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
113287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        // When we're using the vr composer, the assumption is that we've
113387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        // already created the IBinder object for the primary display.
113487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        if (!mHwc->isUsingVrComposer()) {
113587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
113687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        }
113787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
11389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
11399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
11419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
1142f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy        BufferQueue::createBufferQueue(&producer, &consumer,
1143f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy                new GraphicBufferAlloc());
11449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
11459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
11469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
11479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
11489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
11499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
11509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
11519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
11529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
11539e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1154692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
11559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
11569e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1157692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1158692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
11599e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
11609e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
11619e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
11629e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
11633ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
11648630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
11658630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
11663cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onInvalidateReceived(HWComposer* composer) {
11673cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
11683cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer == mHwc) {
11693cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        repaintEverything();
11703cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    } else {
11713cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // This isn't from our current hardware composer. If it's a callback
11723cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // from the real composer, forward the refresh request to vr
11733cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // flinger. Otherwise ignore it.
11743cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        if (!composer->isUsingVrComposer()) {
11753cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas            mVrFlinger->OnHardwareComposerRefresh();
11763cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        }
11773cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
11783cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas}
11793cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
11809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1181faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
11829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
11839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
11848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
11858630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
118687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::clearHwcLayers(const LayerVector& layers) {
118787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    for (size_t i = 0; i < layers.size(); ++i) {
118887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        layers[i]->clearHwcLayers();
118987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
119087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
119187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
119287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::resetHwc() {
119387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    disableHardwareVsync(true);
119487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mDrawingState.layersSortedByZ);
119587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mCurrentState.layersSortedByZ);
119687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // Clear the drawing state so that the logic inside of
119787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // handleTransactionLocked will fire. It will determine the delta between
119887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // mCurrentState and mDrawingState and re-apply all changes when we make the
119987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // transition.
120087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDrawingState.displays.clear();
120187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDisplays.clear();
1202050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    initializeDisplays();
120387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
120487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
1205050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid SurfaceFlinger::updateVrFlinger() {
1206050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!mVrFlinger)
1207050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        return;
1208050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
1209050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
1210209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        return;
1211209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
1212050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay && !mVrHwc) {
1213209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        // Construct new HWComposer without holding any locks.
1214209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        mVrHwc = new HWComposer(true);
1215209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        ALOGV("Vr HWC created");
1216209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
121787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    {
121887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        Mutex::Autolock _l(mStateLock);
121987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
1220050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (vrFlingerRequestsDisplay) {
122187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            resetHwc();
122287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
122387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            mHwc = mVrHwc;
1224050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            mVrFlinger->GrantDisplayOwnership();
122587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        } else {
1226050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            mVrFlinger->SeizeDisplayOwnership();
122787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
122887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            resetHwc();
122987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
123087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            mHwc = mRealHwc;
123187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar            enableHardwareVsync();
123287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        }
123387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
123487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mVisibleRegionsDirty = true;
123587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        invalidateHwcGeometry();
123687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        android_atomic_or(1, &mRepaintEverything);
123787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        setTransactionFlags(eDisplayTransactionNeeded);
123887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
123987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    if (mVrHwc) {
124087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
124187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
124287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
124387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
12451c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
124699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
12476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
12485018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
12495018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
12500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                    (mPreviousPresentFence->getSignalTime() ==
12510a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                            Fence::SIGNAL_TIME_PENDING);
12525018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1253c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
1254af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                ALOGD("Backpressure trigger, skipping transaction & refresh!");
12555018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
12565018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
12575018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
12585018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
1259050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // Now that we're going to make it to the handleMessageTransaction()
1260050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // call below it's safe to call updateVrFlinger(), which will
1261050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // potentially trigger a display handoff.
1262050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            updateVrFlinger();
1263050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
12646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
12656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
12665878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
12676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
12685878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
12695878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
12705878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
12716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
12726b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
12736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
12746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
12756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
12766b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
12776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
12786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
12794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12826b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1283c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard    uint32_t transactionFlags = peekTransactionFlags();
12844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
128587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
12866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
12874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
12886b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
12894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12916b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1292cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
12936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
12944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
12953a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
12964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1297cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
129814cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
129940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
130005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
1301d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    preComposition(refreshStartTime);
130205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
130305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
130405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
130505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
13060a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    postComposition(refreshStartTime);
130705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
130811d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
1309bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1310bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1311bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1312bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1313bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1314bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1315bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
131614cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
13179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1318cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1319cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1320cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1321cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1322cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1323cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1324cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1325cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1326cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1327cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1328cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
13292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1330cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1331cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1332cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1333cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1334cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1335cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1336cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1337cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
13383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
13393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
13403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1341da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1342cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1343cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1344cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1345cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1346cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1347cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1348cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1349cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1350cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1351bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
13529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
13537bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
13547bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
13557bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
13567bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
13577bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
13587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
13599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
13609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1361bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1362cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1363cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1364d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
13669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
13689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1369cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
13702047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
13712047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        if (layer->onPreComposition(refreshStartTime)) {
1372cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1373cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
13742047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
13752047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
1376cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1377cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1378cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1379cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1380a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
13810a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::updateCompositorTiming(
13820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
13830a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        std::shared_ptr<FenceTime>& presentFenceTime) {
13840a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Update queue of past composite+present times and determine the
13850a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // most recently known composite to present latency.
13860a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositePresentTimes.push({compositeTime, presentFenceTime});
13870a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t compositeToPresentLatency = -1;
13880a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (!mCompositePresentTimes.empty()) {
13890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        CompositePresentTime& cpt = mCompositePresentTimes.front();
13900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // Cached values should have been updated before calling this method,
13910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // which helps avoid duplicate syscalls.
13920a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t displayTime = cpt.display->getCachedSignalTime();
13930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        if (displayTime == Fence::SIGNAL_TIME_PENDING) {
13940a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            break;
13950a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        }
13960a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        compositeToPresentLatency = displayTime - cpt.composite;
13970a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
13980a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
13990a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14000a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Don't let mCompositePresentTimes grow unbounded, just in case.
14010a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (mCompositePresentTimes.size() > 16) {
14020a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
14030a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
14040a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1405d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(
1406d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            vsyncPhase, vsyncInterval, compositeToPresentLatency);
1407d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson}
1408d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
1409d001058145c2186f454a3fb043388d6d9b84c9d8Brian Andersonvoid SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
1410d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
14110a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Integer division and modulo round toward 0 not -inf, so we need to
14120a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // treat negative and positive offsets differently.
1413d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
14140a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
14150a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
14160a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1417d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
1418d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    if (idealLatency <= 0) {
1419d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        idealLatency = vsyncInterval;
1420d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
1421d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
14220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snap the latency to a value that removes scheduling jitter from the
14230a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // composition and present times, which often have >1ms of jitter.
14240a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Reducing jitter is important if an app attempts to extrapolate
14250a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // something (such as user input) to an accurate diasplay time.
14260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
14270a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // with (presentLatency % interval).
1428d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t bias = vsyncInterval / 2;
1429d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    int64_t extraVsyncs =
1430d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
1431d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
1432d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
14330a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1434d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
14350a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.deadline = vsyncPhase - idealLatency;
14360a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.interval = vsyncInterval;
1437d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
14380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
14390a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14400a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1441cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
14429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
14439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
14449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
14453546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    // Release any buffers which were replaced this frame
1446f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson    nsecs_t dequeueReadyTime = systemTime();
14473546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    for (auto& layer : mLayersWithQueuedFrames) {
1448f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson        layer->releasePendingBuffer(dequeueReadyTime);
14493546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    }
14503546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson
1451d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
14523d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
14533d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
14543d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
14553d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime =
14563d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
14573d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
14583d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
14593d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
14603d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
14613d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mGlCompositionDoneTimeline.updateSignalTimes();
14623d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
14634e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
14644e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
14654e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    mDisplayTimeline.push(presentFenceTime);
14663d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.updateSignalTimes();
14673d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
14680a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
14690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
14700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14710a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // We use the refreshStartTime which might be sampled a little later than
14720a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // when we started doing work for this frame, but that should be okay
14730a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // since updateCompositorTiming has snapping logic.
14740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    updateCompositorTiming(
14754e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
1476d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    CompositorTiming compositorTiming;
1477d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    {
1478d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
1479d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        compositorTiming = mCompositorTiming;
1480d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
14810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14822047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
14832047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
14844e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                presentFenceTime, compositorTiming);
1485e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
14862047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            recordBufferingStats(layer->getName().string(),
14872047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    layer->getOccupancyHistory(false));
1488e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
14892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
14904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
14914e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    if (presentFence->isValid()) {
14924e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1493faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1494faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1495948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1496faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1497faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1498faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1499cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    if (!hasSyncFramework) {
15002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1501faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1502faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1503faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1504faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
15054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
15064b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
15074b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15084e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (presentFenceTime->isValid()) {
15093d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson            mAnimFrameTracker.setActualPresentFence(
15104e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                    std::move(presentFenceTime));
15114b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
15124b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
15134b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
15149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
15159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
15164b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
15174b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
15184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
15194b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1520b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1521b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1522b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1523b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1524b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1525b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1526b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1527b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1528b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1529b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
15300a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
1531b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1532b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1533b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1534b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1535b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1536b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1537b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1538b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1539cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1540cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1541cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
15429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
15439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
15449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1545cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
1546764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1547764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        ATRACE_CALL();
1548764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        mVisibleRegionsDirty = false;
1549764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        invalidateHwcGeometry();
1550ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
1551764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1552764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region opaqueRegion;
1553764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region dirtyRegion;
1554764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Vector<sp<Layer>> layersSortedByZ;
1555764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
1556764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Transform& tr(displayDevice->getTransform());
1557764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Rect bounds(displayDevice->getBounds());
1558764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            if (displayDevice->isDisplayOn()) {
1559764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                computeVisibleRegions(
1560764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        displayDevice->getLayerStack(), dirtyRegion,
1561764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        opaqueRegion);
1562764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey
1563764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                mDrawingState.traverseInZOrder([&](Layer* layer) {
1564764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    if (layer->getLayerStack() == displayDevice->getLayerStack()) {
1565764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        Region drawRegion(tr.transform(
1566764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                layer->visibleNonTransparentRegion));
1567764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        drawRegion.andSelf(bounds);
1568764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        if (!drawRegion.isEmpty()) {
1569764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layersSortedByZ.add(layer);
1570764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        } else {
1571764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // Clear out the HWC layer if this layer was
1572764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // previously visible, but no longer is
1573764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
1574764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                    nullptr);
1575764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        }
157606a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                    } else {
15778226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changes displayDevice->layerStack upon sleep/awake.
15788226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // Here we make sure we delete the HWC layers even if
15798226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changed their layer stack.
158006a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                        layer->setHwcLayer(displayDevice->getHwcDisplayId(),
158106a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                                nullptr);
158287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
1583764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                });
1584764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            }
1585764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
1586764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.set(bounds);
1587764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.subtractSelf(
1588764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    tr.transform(opaqueRegion));
1589764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->dirtyRegion.orSelf(dirtyRegion);
15903b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
15913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1592cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
15933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1594cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
15959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
15969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
15979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1598028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1599b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1600b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1601b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1602b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1603b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1604b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1605b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1606b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1607b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1608b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1609b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1610b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1611b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1612b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1613b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1614b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1615b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1616b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1617b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1618b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1619b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
16207143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1621b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1622b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1623b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1624b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1625028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1626028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
16279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
16289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
16299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
16309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
16339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
16349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
16359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
1636ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                for (size_t i = 0; i < currentLayers.size(); i++) {
16371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    const auto& layer = currentLayers[i];
16389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
16399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
16409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
16419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
16429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
16439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
16449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1645a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1646a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1647a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1648ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    layer->setGeometry(displayDevice, i);
16499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
16509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
165103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
165203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
165303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
165403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
16559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
165603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
16579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
16589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
16599f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
16609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
16619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
16629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
16639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
16649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
16659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
16669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
16679f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
16689f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
16699f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
16709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
16719f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
16729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
16739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
167438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
167552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
16769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
16779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
16789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
16799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
16807bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
16817bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
16827bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
16837bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
16847bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
16857bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
16869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
16879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
16889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1689cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
169052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1691cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1692cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
16939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
16949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
169552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
169692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
16982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1699cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1700cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
170102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
170202b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
170302b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
170402b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
170887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
17094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
171052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1715841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
17169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1717b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1718a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1719a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1720c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
17219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
17237bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
17247bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
17257bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
17269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
17279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
1728a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard            mHwc->presentAndGetReleaseFences(hwcId);
17299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
17302dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1731b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
17329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
17349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
17359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
17369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
17389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
173952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
17409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
17419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
17429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
17439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1744ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1745e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1746e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1747a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1748a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
17496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
17506547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
17516547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
17526547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
17536547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1758841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1759841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
17607cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
17617cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
17627cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
17637cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
17647cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
17657cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1766ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1767ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1768ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1769ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1770ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1771ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1772ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1773ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1774ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1775ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1776e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
177787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1778ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1779ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1780ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1781ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1782ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
17833d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
178587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
17863d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
17877dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
17882047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([](Layer* layer) {
17892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        layer->notifyAvailableFrames();
17902047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
17917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
17982047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
18002047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (!trFlags) return;
1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
18052047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
18093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1812e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
181392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
181492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
181592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
181892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
182092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
182193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
182292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
182392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
182492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
182592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
182692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
182792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1828e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1829e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
183092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
18313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
183227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
183327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
183427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
183502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1836875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
183702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
183802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
183902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
18409e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
18417adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
184202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
184392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
184492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
184592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
184692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
184792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
18493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1850097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1851097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
18521474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
185493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
185593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
185693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
185702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
185802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
185902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
186093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
186193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
186293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
186393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
186493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
186592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
186693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1867db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
186893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
186993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
187093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
187193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
187200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
187300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
187400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
187500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
187600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
18774fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
187893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
187947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
188047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
188147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
188292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
188392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
188492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
188592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
188692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
188792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
188892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1891cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
189299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1893db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1894b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1895b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1896f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1897f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy                            new GraphicBufferAlloc());
1898db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
18999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
190099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
190102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
190202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
190302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
190499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1905db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
19068cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            if (mUseHwcVirtualDisplays) {
19078cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int width = 0;
19088cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int status = state.surface->query(
19098cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
19108cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
19118cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query width (%d)", status);
19128cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int height = 0;
19138cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
19148cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
19158cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
19168cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query height (%d)", status);
19178cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int intFormat = 0;
19188cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
19198cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
19208cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
19218cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query format (%d)", status);
19228cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                auto format = static_cast<android_pixel_format_t>(
19238cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        intFormat);
19248cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
19258cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
19268cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        &hwcId);
19278cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            }
19289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
19295cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
19305cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
19319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
19329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
19339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
19349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
1935db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1936db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
193747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
193899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
193999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1940cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1941cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1942cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1943cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
194487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
194587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        hwcId = state.type;
194687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
194787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        producer = bqProducer;
1948cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1949cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1950cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
195199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1952cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
19539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                state.type, hwcId, state.isSecure, display,
19549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                dispSurface, producer,
195505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1956cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1957cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
19584fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
19598dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1960cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
19619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
19627adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
19631c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
196493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
196592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
196692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
19683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
19718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
19728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
19738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
19748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
19758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
19768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
19778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
19788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
19798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
19808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
19818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
19828430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
19838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
19848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
19858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
19868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
19878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
19888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
19898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
19908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
19918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
19922047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool first = true;
19932047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
19948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
19958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
19968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
19971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            uint32_t layerStack = layer->getLayerStack();
19982047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (first || currentlayerStack != layerStack) {
19998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
20008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
20018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
20028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
20038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
20048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
20058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
20068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
20078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
20088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
20098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
201091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
20118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
20128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
20138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
20148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
20158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
201691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
201791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
201891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
201991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
202091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
202191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
202291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
202391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
20248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
202591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
20262047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
20272047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            first = false;
20282047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
20298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
20308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
20318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
20323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
20333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
20343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
20351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
20361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (mLayersAdded) {
20371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = false;
20381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        // Layers have been added.
20393559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
20403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
20413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
20423559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
20433559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
20443559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
20453559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
20463559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
20472047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
20481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
20493559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
20503559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
20513559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
20523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
20531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                Region visibleReg;
20541f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                visibleReg.set(layer->computeScreenBounds());
20551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                invalidateLayerStack(layer->getLayerStack(), visibleReg);
20560aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
20572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
2058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
206103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
206203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
206303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
206403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
206503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
206603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
20679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
20689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
20699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
207003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
207103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
20729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
20749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
207503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
207603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
20774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
20784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
20794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
20804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
2081598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
20824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
20831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& l : mLayersPendingRemoval) {
20841f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            recordBufferingStats(l->getName().string(),
20851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    l->getOccupancyHistory(true));
20861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            l->onRemoved();
20874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
20884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
20894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
20904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
20914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
20924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
20934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
20944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
20954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
20961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mDrawingState.traverseInZOrder([](Layer* layer) {
20971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->commitChildList();
20981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    });
20992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
21002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
21014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21042047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
210587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
2106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2107841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
21089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
2109841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
2110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
2112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
2113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
2115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21162047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
2117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
21181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
2119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
21211f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != layerStack)
21222047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            return;
212387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2124ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2125ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
2126ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
2128ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2129ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2130ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
2131ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
2132ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
2133ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
2134ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
2136ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2137ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2138ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
2139ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
2140ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
2142ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2143a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
2144a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
2145a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
2146a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
2147a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
2148a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
2149a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
2150a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
2151a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
2152a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
2153ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2154ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
2155da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
21564125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
21571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Rect bounds(layer->computeScreenBounds());
2158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
21591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Transform tr = layer->getTransform();
2160ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
2161ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
2162ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
216322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
216422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
216522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
21664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
216722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
216822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
216922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
21704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
2171ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2173ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
21741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                const int32_t layerOrientation = tr.getOrientation();
21759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
2176ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
2177ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
2178ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
2179ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2183ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
2184ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
2185ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2186ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
2187ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
2188ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
2190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
2191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
2195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
2196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
21974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
2200a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
2201ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
2202ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
2203ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
2204ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2205ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
2206ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
2207ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
2208ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2209ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
2210ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
2211a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
2212ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
22134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
22144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
2215ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
2216ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
2217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
2219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
222187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
2222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2223ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
2224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
22258b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2226a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
2229a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
2230a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
22312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
2234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
223787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
223892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
22394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
22404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
22414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
224292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
224392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
224487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
224587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
22466b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
22499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2250d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    nsecs_t latchTime = systemTime();
225199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
22524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
22536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
225451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
225551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
225651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
225751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
225851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
225951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
226051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
226151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
226251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
226351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
22642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
22656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
22666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
22676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
22682047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mLayersWithQueuedFrames.push_back(layer);
2269ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2270ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
22716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2272ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2273ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
22746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
22752047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
22762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
22779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
2278d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
2279ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
22801f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        invalidateLayerStack(layer->getLayerStack(), dirty);
22814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
22824da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
22833b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
22846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
22856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
22866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
22876b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
22889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
22896b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
22906b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
22916b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
22926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
22939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
2294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2296ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2297ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
22989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2299ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2300ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
230199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2302830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition(
2303830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        const sp<const DisplayDevice>& displayDevice,
230487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23067143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
23077143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
23087143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
23097143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
2310830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
23117143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
23129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
23137143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
23147143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
23157143316af216fa92c31a60d4407b707637382da1Dan Stoza
23169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
23179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
231887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
231987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2320b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
2321830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2323830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    uint32_t flags = displayDevice->getFlags();
23240f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
232529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
232629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
232729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
2328830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        dirtyRegion.set(displayDevice->swapRegion.bounds());
2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
23300f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
233129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2332df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
233395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
23340f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
2335830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->swapRegion.bounds());
2336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
233729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
2338830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->bounds());
2339830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            displayDevice->swapRegion = dirtyRegion;
2340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2343830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
2344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23459c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
2346830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2347da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2348da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2349830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapBuffers(getHwComposer());
2350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
23539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
23569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
23579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
23589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
23599f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
23609f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
23619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
23629f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
23639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
23649f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
23659f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
23669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
23679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
23689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
23699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2370a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
23719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2372c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
23739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
23743f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
23753f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
23763f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
23773f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
23783f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2379c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2380a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2381a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
23829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
23839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2384b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2385b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2386b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
23873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2388b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
23899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2390b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2391766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
23929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2393766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2394766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2395766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2396766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
23979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2398766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2399766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
24009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2401766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2402766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2403766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2404766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2405b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
240687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2407b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
24089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2409b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2410a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2411f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
24129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2413766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2414f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2415f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
24169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
24179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2418f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2419f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2420f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2421f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
24223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2423f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
24249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
24259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
24263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2427f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2428f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
242985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
24304b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
243185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
243285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
243385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
24344b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
24359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
24369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
24379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
243885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
24399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
24409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
24419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
24429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
24439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
24449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
24459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
244685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
24479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
24489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
24499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
2450267ab79b22f9d0b995ff787e36aca9c39497c489Gray Huang                    case HWC2::Composition::Sideband:
24519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2452ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
24539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
24549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
24559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2456cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2457cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
24581748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard                            layer->clearWithOpenGL(displayDevice);
2459cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
246085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
246185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
24629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
24639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
246485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2465a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
24669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2467da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2468cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
24699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
24709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2471a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
24729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
247385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
247485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
247585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
24769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
247785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
24789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
247985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
24809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
248185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
24824b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
24834b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2484f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
24859f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
24869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
24879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
24889f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2489f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
24909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
24913f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2494830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
2495830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    const int32_t height = displayDevice->getHeight();
24963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
24973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2501ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
25026710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
25031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& lbc,
25041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& parent)
25051b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
25067d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
25077d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
25087d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
25091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (mNumLayers >= MAX_LAYERS) {
25107d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
25117d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
25121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (parent == nullptr) {
25131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            mCurrentState.layersSortedByZ.add(lbc);
25141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        } else {
25151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            parent->addChild(lbc);
25161f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
25177d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
25181f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = true;
25191f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mNumLayers++;
25207d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
25217d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
252296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2523ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
25244f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
25257d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
252696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
252796f0819f81293076e652792794a961543e6750d7Mathias Agopian
25289524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carrstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
25297f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr    Mutex::Autolock _l(mStateLock);
25307f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr
25311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const auto& p = layer->getParent();
25321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
25331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.layersSortedByZ.remove(layer);
25341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
2535136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // As a matter of normal operation, the LayerCleaner will produce a second
2536136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // attempt to remove the surface. The Layer will be kept alive in mDrawingState
2537136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // so we will succeed in promoting it, but it's already been removed
2538136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // from mCurrentState. As long as we can find it in mDrawingState we have no problem
2539136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // otherwise something has gone wrong and we are leaking the layer.
2540136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) {
25411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        ALOGE("Failed to find layer (%s) in layer parent (%s).",
25421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->getName().string(),
25431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (p != nullptr) ? p->getName().string() : "no-parent");
25441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        return BAD_VALUE;
2545136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    } else if (index < 0) {
2546136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr        return NO_ERROR;
2547598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
25481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
25491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersPendingRemoval.add(layer);
25501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersRemoved = true;
25511f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mNumLayers--;
25521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    setTransactionFlags(eTransactionNeeded);
25531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    return NO_ERROR;
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2556c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() {
2557dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2558dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2559dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
25603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
256799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25728b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
25738b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
25748b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
25758b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
25768b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
25777c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2578698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
257928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25812d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
25822d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
25832d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
25842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
25857c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
25862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
25872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
25887c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
25897c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
25907c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
25912d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
25922d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
25932d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
25942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
25952d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
25962d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2597e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2598e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2600e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2601b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2602b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2604698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2605698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2606d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2607d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2608d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2609d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2610d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2611d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2612d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2613d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2614097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2615d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
26162ae83f4f628d4da96f363d0668380ba1f753b867Fabien Sanglard                if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
2617d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2618d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2619d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2620d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2621d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2622698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2623386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
26242a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
26252a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
26262a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
26272a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
26282a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
26292a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
26302a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
263128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2632ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2633ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2634ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2635468051e20be19130572231266db306396a56402bIrvel
2636386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
263728378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2638698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2639386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2640386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2641386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
26422d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
26432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
26442d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
26452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2646386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
26472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2648386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2649386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2650386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2651386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
26522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
26532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2654386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2655386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2656cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2660e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2661e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
26629a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
26639a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
26649a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
26659a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2666e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
26679a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
26683ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2669e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2670e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2671097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2672e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2673e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2674e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2675e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2676e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2677e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2678e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2679e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2680e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2681e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
268200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2683e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2684e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2685e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2686e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2687e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2688e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2689e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2690e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2691e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2692e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2693e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2694e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2695e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
269647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
269747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
269847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
269947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
270047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
270147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
270247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
270347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
270447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
270547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2706e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2707e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2708e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2709e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2710e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2711e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2712e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2713e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2714e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
271513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2716e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2717e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
271899e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
271999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2720e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
272199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2722e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
272382364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2724e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2725e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2726e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
27271f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            const auto& p = layer->getParent();
27281f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (p == nullptr) {
27291f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
27301f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (layer->setLayer(s.z) && idx >= 0) {
27311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.removeAt(idx);
27321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.add(layer);
27331f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // we need traversal (state changed)
27341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // AND transaction (list changed)
27351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
27361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
27371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else {
27381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (p->setChildLayer(layer, s.z)) {
27391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
27401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
2741e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2742e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2743e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2744e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2745e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2746e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2747e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2748e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
27499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2750e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2751e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2752e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2753e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2755e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2756e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2757e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2758e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2759e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2760231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2761e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2762e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2763e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2764e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
276599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2766e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2767e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2768acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2769acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2770acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2771acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2772e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2773e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
27741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // We only allow setting layer stacks for top level layers,
27751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // everything else inherits layer stack from its parent.
27761f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->hasParent()) {
27771f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
27781f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        layer->getName().string());
27791f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (idx < 0) {
27801f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer without parent (%s) that "
27811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        "that also does not appear in the top level layer list. Something"
27821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        " has gone wrong.", layer->getName().string());
27831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (layer->setLayerStack(s.layerStack)) {
2784e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2785e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2786e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2787e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2788e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2789e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2790e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
27917dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
27920d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            if (s.barrierHandle != nullptr) {
27930d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
27940d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            } else if (s.barrierGbp != nullptr) {
27950d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
27960d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                if (authenticateSurfaceTextureLocked(gbp)) {
27970d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    const auto& otherLayer =
27980d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
27990d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
28000d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                } else {
28010d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    ALOGE("Attempt to defer transaction to to an"
28020d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                            " unrecognized GraphicBufferProducer");
28030d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                }
28040d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            }
28057dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
28067dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
28077dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
28081db73f66624e7d151710483dd58e03eed672f064Robert Carr        if (what & layer_state_t::eReparentChildren) {
28091db73f66624e7d151710483dd58e03eed672f064Robert Carr            if (layer->reparentChildren(s.reparentHandle)) {
28101db73f66624e7d151710483dd58e03eed672f064Robert Carr                flags |= eTransactionNeeded|eTraversalNeeded;
28111db73f66624e7d151710483dd58e03eed672f064Robert Carr            }
28121db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
28139524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        if (what & layer_state_t::eDetachChildren) {
28149524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr            layer->detachChildren();
28159524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        }
2816c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2817c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2818c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2819c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2820c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
28254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
28260ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
28270ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
28284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
2829479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
2830479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
2831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
28326e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2833921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
28346e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
28354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
28366e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
28378b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
28384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
28394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
28404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
28414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
28423165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
28433165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
28444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
28454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
28464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
28483165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
28494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
28504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
28514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
28524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
28534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
28544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28587d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
28597d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
28617d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
2862479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk    layer->setInfo(windowType, ownerUid);
2863479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk
28641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result = addClientLayer(client, *handle, *gbp, layer, *parent);
28657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
28667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
28677d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
2868ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
28697d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
28707d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
28714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
28754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
28764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
287992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
28858f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
28904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
28914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
28924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2893b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
28954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
28964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
28974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
29014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
29024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
29054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2906b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
29074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2908118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2909118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2910ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
29119a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
29129524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    // called by a client when it wants to remove a Layer
29136710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
29146710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
29156710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
2916ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
29176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
29186710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
29196710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
29209a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
29219a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
29229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
29239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
292413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29266710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
29276710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
29289524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    sp<Layer> l = layer.promote();
29299524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    if (l == nullptr) {
29309524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // The layer has already been removed, carry on
29319524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
29329524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    } if (l->getParent() != nullptr) {
29339524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // If we have a parent, then we can continue to live as long as it does.
29349524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
29359524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    }
29369524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    return removeLayer(l);
2937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2939b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2940b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
294113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
294201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
294313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
294413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
294513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
294601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
294701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2948692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
294901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
295013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
29514c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
29524c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
295347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
295447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
295513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
295613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
29572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
29586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
29599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
29609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
29616547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
29620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
2963d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use phase of 0 since phase is not known.
2964d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use latency of 0, which will snap to the ideal latency.
2965d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(0, period, 0);
296613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
296713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
296813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
296913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
297013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
297113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
2972c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
297313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
297413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
297513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
297613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
297713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
297813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
297913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
298013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
298113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
29822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
29832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
29842c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
29852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
29862c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
29872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
298813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
29892c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
29902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2991c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2992c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2993c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
29942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
29952c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
29962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
29972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
29982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2999c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
3000ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
3001ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
3002ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
3003ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
3004ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
3005ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
3006ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
3007ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
3008ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
3009ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
30102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
3011f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
30122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3013c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3014c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
3015c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
3016948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
3017c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
3018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
3020b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
30212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
3022f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3023f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3024f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
3025f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
3026f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
3027f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
30282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
3029f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
3030f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3031f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
3032f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
3033f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
3034f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3035c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3036948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
3037948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
3038cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
3039cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
3040cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
3041c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
30422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
30432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
30442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
30452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
30462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3047b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
3048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
30512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
3052db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
3053db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
30542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
3055b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
30562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
30572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
30582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
3059b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
30602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
3061db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
30622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
30637306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
30649e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
30652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
30662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
3067db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
30682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
3069db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
3070b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
3071b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
3072b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
30732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
3074db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
3075b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
3076b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3077b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
3078b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
3080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
308299b49840d309727678b77403d6cc9f920111623fMathias Agopian
3083bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
3084bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
3085bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
3086bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
3087bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
308874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
3089bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
3090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
3091fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
30929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
30939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
3094fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
3095fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
30969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
3097fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
3098fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
3099fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
31009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
31019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
310282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
310382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
310425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
310525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
310625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
310725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
310825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
310974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
311035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
311125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
311225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
311325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
311425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
311582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
311674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
311735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
311882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
311925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
312025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
312125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
312225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
312374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
312435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
312525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
3126c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
3127c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
3128c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
3129c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
3130c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
3131c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
3132c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
3133b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3134b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
3135b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
3136b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
3137b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
3138b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
3139b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
314040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
314140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
3142d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    (args[index] == String16("--frame-events"))) {
314340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
3144d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                dumpFrameEventsLocked(result);
314540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
314640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
3147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
31481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
314982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
315074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
315182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
315248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
315382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
315482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
315548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
315682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
315782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
315882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
315982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
316048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
3161c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
3162c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
316325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
31642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
316574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
31662047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
316725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
316825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
316982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
317074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
317182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
317282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
317382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
317482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
317582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
317682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
317748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
31789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
31799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
318086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
31814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
31824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
3183d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
31844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
31852047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
31864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
3187d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
31884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
31892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
319082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
319182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
3192ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
319325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
3194c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
319525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
319625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
319725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
319825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
319925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
320025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
320125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
32022047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
320325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
3204d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
320525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
32062047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
32074b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
3208d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
320925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
321025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
32116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
32126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
32136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
32142047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
32156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
32162047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
32176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
32186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
32196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
32206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
322163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const
32224803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
322363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" [sf");
3224c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    result.appendFormat(" HAS_CONTEXT_PRIORITY=%d", useContextPriority);
3225c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
322663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    if (isLayerTripleBufferingDisabled())
322763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard        result.append(" DISABLE_TRIPLE_BUFFERING");
3228c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
3229c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset);
3230a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
3231c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
3232cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
32331971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
32341971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard                        maxFrameBufferAcquiredBuffers);
323563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append("]");
32364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
32374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
3238b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
3239b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
3240b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
3241b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
3242b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
3243b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
3244b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
3245b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
3246b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
3247b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
3248b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
3249b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
3250b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
3251b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
3252b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
3253b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
3254b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3255e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
3256e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
3257e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3258e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
3259e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
3260e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
3261e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
3262e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3263e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
3264e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
3265e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
3266e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
3267e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3268e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
3269e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
3270e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3271e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3272e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3273d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
3274d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("Layer frame timestamps:\n");
3275d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3276d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
3277d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const size_t count = currentLayers.size();
3278d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    for (size_t i=0 ; i<count ; i++) {
3279d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        currentLayers[i]->dumpFrameEvents(result);
3280d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
3281d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
3282d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3283e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
3284e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
3285e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
3286e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
3287e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3288e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
3289e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
3290e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
3291e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
3292e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
3293e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
3294e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
3295e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3296e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
3297e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
3298e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
3299e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
3300e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
3301e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
3302e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
3303e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
3304e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3305e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3306e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3307e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3308e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3309e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3310e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3311e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3312e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3313e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3314e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3315e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3316e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3317e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
331874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
331974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
332082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
33213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
33223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
33233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
33243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
33253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
33263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
33273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
33283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
33293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
333082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
333182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
333282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
333382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
333482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
333582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3336bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
333782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
33384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
33394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
33403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
33413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
33424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
33433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
33444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
33454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
33464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
33474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
33484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
33493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3350ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
33513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3352ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3353ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3354ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
33559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
33569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
335741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
335841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
335941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
336024cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
3361c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
33629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
3363c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard        dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
336441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
336541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3366b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3367b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3368b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3369b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3370b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3371e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3372e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
33734803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
337482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
337582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
33763e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
33771f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
33783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
33792047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
33803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
33812047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3382bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
338382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
33845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
33855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
33865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
33873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
338886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
33893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
33905f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
33915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
339274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
33935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
33945f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
33955f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
339682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
339782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
33981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
33993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
340074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
34013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
34021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3403888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
34044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3405ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
34063e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
34073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
34083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
34093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
34103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3411ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3412ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3413875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
34149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
34154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
34162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
34172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
341874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
341982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
342082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3421c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
342282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
342382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3424ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3425ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3426ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
342782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
342882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3429c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
34309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
34319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
34329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3433ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
343482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
343574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
343682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
343782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
343874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
343982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
344082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
344182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
344282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
344382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
344474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3445e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3446e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3447e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3448e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3449e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3450e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3451e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3452e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3453e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3454e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3455e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3456e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3457e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3458e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
34591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
3460e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
34611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
3462e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3463e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
346482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
346582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
346682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
346782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
34683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
346974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
34703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
34719f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
34729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
34739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
347474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
347582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
347682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
347782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
347882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
347982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
348082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
348448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3485db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
348648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
348748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
348848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
348948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
349048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
349148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
349248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
349348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
349448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
349548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
349648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
349748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
349848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3499cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3500cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
350163f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
350263f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
350363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
350463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
350563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
350663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
350763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
350863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
350963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
351024cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
351163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
351263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
351363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
351463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
351563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
351663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
351763f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
351863f165fd6b86d04be94d4023e845e98560504a96Keun young Park
35196e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3522041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3524d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3525d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
35262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3527c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3532a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
35333bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
353499b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
35356e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3536375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
35381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
35391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
35401db73f66624e7d151710483dd58e03eed672f064Robert Carr        /*
35411db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Calling setTransactionState is safe, because you need to have been
35421db73f66624e7d151710483dd58e03eed672f064Robert Carr         * granted a reference to Client* and Handle* to do anything with it.
35431db73f66624e7d151710483dd58e03eed672f064Robert Carr         *
35441db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
35451db73f66624e7d151710483dd58e03eed672f064Robert Carr         */
35461db73f66624e7d151710483dd58e03eed672f064Robert Carr        case SET_TRANSACTION_STATE:
35471db73f66624e7d151710483dd58e03eed672f064Robert Carr        case CREATE_SCOPED_CONNECTION:
35481db73f66624e7d151710483dd58e03eed672f064Robert Carr        {
35491db73f66624e7d151710483dd58e03eed672f064Robert Carr            return OK;
35501db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
35511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
35521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
35531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
35541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
35551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
35561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
355799b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
355899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
35596e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
35601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
35611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
35621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
35656e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
35666e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
35676e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
35686e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
35696e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
35706e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
35716e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
35726e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
35736e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
35746e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
35751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3578b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
357999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3580375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3581375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3582375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3583e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3584375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
358901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
359035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
359553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
359653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
359953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3600cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3601cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3602cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3603e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3605e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3607cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
36094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
36104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
36114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
36124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
361353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
361453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
361553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
361653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
361753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
361853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3619a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3620a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3621a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3622a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3623a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3624a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
362601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3629b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
363012839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
36344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
36354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3636ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3637ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3638ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3639ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3640ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3641ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
36429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
36439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
36449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
36459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
36469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
36479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
36489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
36499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
36509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
36519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
36529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
36539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3654ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3655ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
36569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3657ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
36589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3659ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3660ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3661ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
36629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
36639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
36649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
36659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
36669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
36679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
36689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
36699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
36709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3671794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
36729f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
36739f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
36749f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
36759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
36769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
36779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
36789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
36799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
36809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
36819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3683f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3684f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3685f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3686645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3687645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3688f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3689f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3690ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3691ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3692ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3693ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3694ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3695db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3696db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3697db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3698db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3699db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3700db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3701db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3702db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3703db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3704db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3705468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3706468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3707468051e20be19130572231266db306396a56402bIrvel                if (n) {
3708468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3709ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3710468051e20be19130572231266db306396a56402bIrvel                }
3711468051e20be19130572231266db306396a56402bIrvel                else{
3712468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3713468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3714468051e20be19130572231266db306396a56402bIrvel                }
3715468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3716468051e20be19130572231266db306396a56402bIrvel            }
37178cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
37188cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
37198cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
37208cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
37218cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
372753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
372887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
372999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
373053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
373153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
373259119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
37332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
37342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
373559119e658a12279e8fff508f8773843de2d90917Mathias Agopian
37362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
37372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
37382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3739b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3740b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3741b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3742b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
37432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
37442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3745b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3746b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3747b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3748b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3749b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3750b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3751b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3752b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3753b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3754b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3755b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3756b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3757b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3758b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
37592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
37602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
37612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
37622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
37632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3764b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
37652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
37662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
37672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
37682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
37692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
37702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
37712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
37722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
37732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
37742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3775b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3776b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3777b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
37782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
37792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3780c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
37812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
37822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
37832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
37842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3785b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3786b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3787b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3788b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
37892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
37902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
37912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3792b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3793b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3794b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
37952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
37962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
37972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3798c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
37992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
38002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
38012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3802b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
38032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
38042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
38052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3806b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3807b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3808b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3809b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3810097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
38112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3812b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
38132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
38142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
38152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
38162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
38172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3818c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3819b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3820b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
382153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3822b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
382353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
382453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
382553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
382653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3827b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3828b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3829b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
38302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
38312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
38322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
38332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
38342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
38352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
38362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3837b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
38382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3839aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
38402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3841b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3842b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3843b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
38442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
38452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
38462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
38472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
38482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
38492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
38502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3851c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3852ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3853c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
38542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
38552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
38562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
38572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
38582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
38592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
38602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
38615ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
38625ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
38635ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3864b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
38655ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3866c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3867c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3868c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3869c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3870c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3871c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3872c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3873c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3874c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3875c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3876c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3877c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3878c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3879c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3880c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3881c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3882c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3883c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3884c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3885c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3886c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
38872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
38882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
38892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
38902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3891c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
38922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
38932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3894c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3895c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
38962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3897b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
38982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
38992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
39002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
39012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3902c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3903ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                int32_t minLayerZ, int32_t maxLayerZ,
3904b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3905b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3906b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
39072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3908c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
39092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3910c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3911b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3912b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
39132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
39142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
39152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
39162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
39172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
39182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
39192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
39202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3921c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3922c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3923b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3924097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
39252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
39262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
39272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
39282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
39292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
39302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
39312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
39322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
39332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
39352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
39362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
39372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3938c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3939b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
39402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
39422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
39432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
39442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
39452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3946118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3947118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3948180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3949180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3950180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3951c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3952ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
3953c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3954180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3955180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
39563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3957180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3958180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
395989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
396089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
396189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
39620e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3963180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3964c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3965c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3966c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3967c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3968c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3969c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3970c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3971c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3972c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3973c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3974c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3975be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3976be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3977c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3978c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3979c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3980c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3981be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3982be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3983c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3984c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3985180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
39863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3987180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3988180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3989c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3990c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
39913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3992180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3993180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
39943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3995180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
39961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // We loop through the first level of layers without traversing,
39971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // as we need to interpret min/max layer Z in the top level Z space.
39981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
39991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != hw->getLayerStack()) {
40001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
40011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
40021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
40031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (state.z < minLayerZ || state.z > maxLayerZ) {
40041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4005180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
40061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer* layer) {
40071f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (!layer->isVisible()) {
40081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                return;
40091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
40101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(true);
40111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            layer->draw(hw, useIdentityTransform);
40121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(false);
40131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
40141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4015180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4016931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
4017180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
4018180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4019180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
40202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
40212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
40222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
4023c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4024ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4025b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
4026b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
402774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
4028fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
4029fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
4030180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
40313502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
40323502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
40333502416204d9dbd905012ee586d8bd145323809fDan Stoza
40343502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
40353502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
40363502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
4037180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4038180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
4039180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
4040180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
4041180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
4042180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
4043180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4044180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
4045180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
4046180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4047b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
40481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
4049b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
40501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if ((layer->getLayerStack() != hw->getLayerStack()) ||
40511f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (state.z < minLayerZ || state.z > maxLayerZ)) {
40521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4053b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
40541f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer *layer) {
40551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
40561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    layer->isSecure());
40571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
40581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4059b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
4060b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
4061b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
4062b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
4063b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
4064b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
40650aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
40660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
406783cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
4068605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
4069605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
4070605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
4071605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
4072605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
4073605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
4074605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
4075605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
40760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
407774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
40785a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
40795a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
40803ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
40813ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
40822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
40840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
40854ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
40860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
40870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
40882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
40900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
40910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
40920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
40930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
40940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
40950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
4096866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
40970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
40980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
40990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
41000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
41010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
41023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
41033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
41043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
41053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
41060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
41070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
41080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
41090aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
4110c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
4111c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
4112c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
4113d555684cb36dfb959694db76962e570184f98838Mathias Agopian
4114866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
4115866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
4116866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
4117866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
4118866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
4119866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
41209707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
41219707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
4122866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4123866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
4124866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
41252d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
4126866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
4127866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
4128866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
4129866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
4130866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
4131866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
41322d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
4133866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4134866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
4135866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
4136866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
4137866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
4138866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
4139866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
4140866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
4141866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
4142866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
4143866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
4144866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
4145866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
4146866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
41472d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
4148866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
41492d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
41502d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
4151d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
4152d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
4153d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
4154d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
4155d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
4156d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
4157d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
4158d555684cb36dfb959694db76962e570184f98838Mathias Agopian
41590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
41600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
41610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
4162f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
4163f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
41640aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
41650aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
41660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
41670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
41680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
416974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
4170f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
4171f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
4172f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
4173f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
417474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
41750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
41760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
417774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
41780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
417974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
418074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
418174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
418274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
418374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
4184d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
4185ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) {
4186fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
4187d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
4188d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
4189d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
4190fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
4191fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
4192fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
4193fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
4194fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
4195fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
41961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
41972047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        size_t i = 0;
41981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& layer : mDrawingState.layersSortedByZ) {
4199fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
42001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ &&
42011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    state.z <= maxLayerZ) {
42021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->traverseInZOrder([&](Layer* layer) {
42031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
42041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            layer->isVisible() ? '+' : '-',
42051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            i, layer->getName().string(), layer->getLayerStack(), state.z,
4206fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
42071f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    i++;
42081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                });
42091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
42101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
4211fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
4212ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
4213ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
42141b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
42151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
42162047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
42172047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInZOrder(consume);
4218921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4219921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
42202047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
42212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInReverseZOrder(consume);
4222921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4223921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
4224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
42253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
42263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
42273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
42283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
42293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
42303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
42313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
42323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
42333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
4234