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