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 55122752851180b26f8d797b3fe5f7e99ad0eeaf7eeTim Murray // set EventThread and 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 } 55722752851180b26f8d797b3fe5f7e99ad0eeaf7eeTim Murray if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { 55822752851180b26f8d797b3fe5f7e99ad0eeaf7eeTim Murray ALOGE("Couldn't set SCHED_FIFO for EventThread"); 55922752851180b26f8d797b3fe5f7e99ad0eeaf7eeTim Murray } 56041a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray 5619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Get a RenderEngine for the given display / config (can't fail) 5629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine = RenderEngine::create(mEGLDisplay, 5639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza HAL_PIXEL_FORMAT_RGBA_8888); 5649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 565f9481058101c4e2b38c74048feac383664691d03Saurabh Shah 5669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Drop the state lock while we initialize the hardware composer. We drop 5679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // the lock because on creation, it will call back into SurfaceFlinger to 5689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize the primary display. 569050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay, 570050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "Starting with vr flinger active is not currently supported."); 5713cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas mRealHwc = new HWComposer(false); 57287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar mHwc = mRealHwc; 5739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this)); 574b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 5759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 576875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 5775c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott // Inform native graphics APIs whether the present timestamp is supported: 5785c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott if (getHwComposer().hasCapability( 5795c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott HWC2::Capability::PresentFenceIsNotReliable)) { 5805c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott property_set(kTimestampProperty, "0"); 5815c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott } else { 5825c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott property_set(kTimestampProperty, "1"); 5835c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott } 5845c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott 585050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (useVrFlinger) { 586050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) { 5872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGI("VR request display mode: requestDisplay=%d", requestDisplay); 588050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas mVrFlingerRequestsDisplay = requestDisplay; 589050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas signalTransaction(); 590050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas }; 591050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(), 592050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas vrFlingerRequestDisplayCallback); 593050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (!mVrFlinger) { 594050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGE("Failed to start vrflinger"); 595050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 596050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 597050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 598875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 599875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 600a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 601da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 602da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 603da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 6049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // make the GLContext current so that we can create textures when creating 6059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Layers (which may happens before we render something) 6067d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext); 607a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 608d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 609d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 610d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 61192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 61292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 6138630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 61413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 61513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 61613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 6174e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza mRenderEngine->primeCache(); 6184e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza 619b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang mStartBootAnimThread = new StartBootAnimThread(); 620b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang if (mStartBootAnimThread->Start() != NO_ERROR) { 621b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang ALOGE("Run StartBootAnimThread failed!"); 622b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang } 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Done initializing"); 6253ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 6263ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 627a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 628b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // Start boot animation service by setting a property mailbox 629b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // if property setting thread is already running, Start() will be just a NOP 630b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang mStartBootAnimThread->Start(); 631b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // Wait until property was set 632b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang if (mStartBootAnimThread->join() != NO_ERROR) { 633b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang ALOGE("Join StartBootAnimThread failed!"); 634b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang } 635a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 636a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 637875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 638875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 639a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 640a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 641875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 642875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 643a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 644a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 646d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 647582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 6482adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 649134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 6500d48072f6047140119ff194c1194ce402fca2c0bRobert Carr return authenticateSurfaceTextureLocked(bufferProducer); 6510d48072f6047140119ff194c1194ce402fca2c0bRobert Carr} 6520d48072f6047140119ff194c1194ce402fca2c0bRobert Carr 6530d48072f6047140119ff194c1194ce402fca2c0bRobert Carrbool SurfaceFlinger::authenticateSurfaceTextureLocked( 6540d48072f6047140119ff194c1194ce402fca2c0bRobert Carr const sp<IGraphicBufferProducer>& bufferProducer) const { 655097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 6566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 657134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 658134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 6596b376713907086c9642e7b7e66e51ddfa531b003Brian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps( 6606b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson std::vector<FrameEvent>* outSupported) const { 6616b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson *outSupported = { 6626b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::REQUESTED_PRESENT, 6636b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::ACQUIRE, 6646b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::LATCH, 6656b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::FIRST_REFRESH_START, 6666b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::LAST_REFRESH_START, 6676b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::GPU_COMPOSITION_DONE, 6686b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::DEQUEUE_READY, 6696b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::RELEASE, 6706b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson }; 6716b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson if (!getHwComposer().hasCapability( 6726b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson HWC2::Capability::PresentFenceIsNotReliable)) { 6736b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson outSupported->push_back(FrameEvent::DISPLAY_PRESENT); 6746b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson } 6756b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson return NO_ERROR; 6766b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson} 6776b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson 6787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 6797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 68023e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa if ((configs == NULL) || (display.get() == NULL)) { 6817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 6827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6847aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 6857aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 6867aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 687692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 6889e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 689692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 6901604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 6911604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 6921604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6931604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6941604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6951604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 6961604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 697c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 6988b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6998b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 7008b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 7018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 7028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 7038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 7048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 7058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 7068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 7078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 7088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 7098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 7108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 7118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 7128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 7138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 7148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 7151604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 7167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 7177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (const auto& hwConfig : getHwComposer().getConfigs(type)) { 7197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 7207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float xdpi = hwConfig->getDpiX(); 7229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float ydpi = hwConfig->getDpiY(); 7237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 7257f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 7267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 7277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 7287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 7297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 7307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 7317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 7327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 7337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 7347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 7357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 7367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 7377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 7387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 7397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 7418722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 7428722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk info.orientation = hw->getOrientation(); 7437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 7447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 7457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 7467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 7477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 7481604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 7497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.w = hwConfig->getWidth(); 7519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.h = hwConfig->getHeight(); 7527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 7537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 7549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.fps = 1e9 / hwConfig->getVsyncPeriod(); 7554b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park info.appVsyncOffset = vsyncPhaseOffsetNs; 7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 75791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 75891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 75991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 76091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 76191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 76291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 76391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 76491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 76591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 76691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 76791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 76891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 7699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.presentationDeadline = hwConfig->getVsyncPeriod() - 7700cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard sfVsyncPhaseOffsetNs + 1000000; 7717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 7727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 7737f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 7747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright configs->push_back(info); 7768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 7778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 7787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 7797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 780dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 78189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 78267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 78367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 78467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 78567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 78667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 78767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 78867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 78967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 79067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 79167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 79267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 79367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 7946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 7959f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong if (display == NULL) { 7969f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong ALOGE("%s : display is NULL", __func__); 7979f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong return BAD_VALUE; 7989f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong } 7997d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 8007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> device(getDisplayDevice(display)); 80124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 80224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 80324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 8047d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 80524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 8067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 807dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 8086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 8096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 8106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 8116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 8126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 8136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 8146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 8156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 8166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 8176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 8186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 8196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 8206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 8216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 8226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 8236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 8246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 8256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 8266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 8276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 8286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 8296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 8306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 8316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 8326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 8336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 8346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 8356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 8366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 8376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 8387306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 8397306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 840784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 8419ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 8427306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 8447306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 8456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 8466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 8476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 8487306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 8496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 8506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 8516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 8526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 8536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 8546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 8556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 8566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 8576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 8586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 8596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 860888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 861c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display, 86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t>* outColorModes) { 86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if ((outColorModes == nullptr) || (display.get() == nullptr)) { 86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return BAD_VALUE; 86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 86728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 86828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (!display.get()) { 86928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NAME_NOT_FOUND; 87028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 87128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 87228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = NAME_NOT_FOUND; 87328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 87428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (display == mBuiltinDisplays[i]) { 87528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright type = i; 87628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright break; 87728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 87828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 87928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 88028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type < 0) { 88128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return type; 88228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 88328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 88428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type); 88528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright outColorModes->clear(); 88628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); 88728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 88828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 88928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 89028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 89128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) { 8927d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> device(getDisplayDevice(display)); 89328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (device != nullptr) { 89428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return device->getActiveColorMode(); 89528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 89628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return static_cast<android_color_mode_t>(BAD_VALUE); 89728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 89828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 89928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw, 90028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) { 90128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = hw->getDisplayType(); 90228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t currentMode = hw->getActiveColorMode(); 90328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 90428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mode == currentMode) { 90528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 90628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 90728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 90828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 90928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Trying to set config for virtual display"); 91028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 91128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 91228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 9135d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGD("Set active color mode: %s (%d), type=%d", decodeColorMode(mode).c_str(), mode, 9145d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter hw->getDisplayType()); 9155d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 91628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright hw->setActiveColorMode(mode); 91728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright getHwComposer().setActiveColorMode(type, mode); 91828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 91928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 92028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 92128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display, 92228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t colorMode) { 92328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright class MessageSetActiveColorMode: public MessageBase { 92428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright SurfaceFlinger& mFlinger; 92528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<IBinder> mDisplay; 92628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mMode; 92728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright public: 92828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp, 92928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) : 93028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger(flinger), mDisplay(disp) { mMode = mode; } 93128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright virtual bool handler() { 93228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t> modes; 93328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.getDisplayColorModes(mDisplay, &modes); 93428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes); 93528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mMode < 0 || !exists) { 9365d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGE("Attempt to set invalid active color mode %s (%d) for display %p", 9375d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode, mDisplay.get()); 93828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 93928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 94028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 94128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (hw == nullptr) { 9425d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGE("Attempt to set active color mode %s (%d) for null display %p", 9435d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode, mDisplay.get()); 94428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 9455d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGW("Attempt to set active color mode %s %d for virtual display", 9465d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode); 94728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else { 94828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.setActiveColorModeInternal(hw, mMode); 94928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 95028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 95128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 95228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright }; 95328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode); 95428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright postMessageSync(msg); 95528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 95628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 957c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 958d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 959d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 960d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 961d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 962d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 963d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 964d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 965d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 966d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 967d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 968d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 969d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 970c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, 971c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza HdrCapabilities* outCapabilities) const { 972c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza Mutex::Autolock _l(mStateLock); 973c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 9747d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> displayDevice(getDisplayDeviceLocked(display)); 975c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (displayDevice == nullptr) { 976c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get()); 977c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 978c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 979c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 980c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::unique_ptr<HdrCapabilities> capabilities = 981c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); 982c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (capabilities) { 983c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::swap(*outCapabilities, *capabilities); 984c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } else { 985c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 986c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 987c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 988c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return NO_ERROR; 989c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza} 990c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 991c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) { 992c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable == mInjectVSyncs) { 993c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 994c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 995c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 996c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable) { 997c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 998c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections enabled"); 999c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mVSyncInjector.get() == nullptr) { 1000c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector = new InjectVSyncSource(); 1001ab04685578b254c2eaf43bf5da85e5e922787825Irvel mInjectorEventThread = new EventThread(mVSyncInjector, *this, false); 1002c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1003c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mInjectorEventThread); 1004c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } else { 1005c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 1006c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections disabled"); 1007c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mSFEventThread); 1008c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector.clear(); 1009c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1010c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 1011c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 1012c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 1013c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) { 1014c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (!mInjectVSyncs) { 1015c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGE("VSync Injections not enabled"); 1016c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return BAD_VALUE; 1017c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1018c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) { 1019c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("Injecting VSync inside SurfaceFlinger"); 1020c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector->onInjectSyncEvent(when); 1021c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1022c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 1023c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 1024c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 1025d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 1026d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 1027b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggisp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection( 1028b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi ISurfaceComposer::VsyncSource vsyncSource) { 1029b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi if (vsyncSource == eVsyncSourceSurfaceFlinger) { 1030b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi return mSFEventThread->createEventConnection(); 1031b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi } else { 1032b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi return mEventThread->createEventConnection(); 1033b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi } 1034bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 1035bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 103799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 103899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 103999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 104099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 104199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 104299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 104399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 104499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 104599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 104699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 104799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 104899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 104999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 105099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 105199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 105299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 105399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 105499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 1055c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 105699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 105799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 105899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 105999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 1060c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 106199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 106299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 106399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 106499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 106599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 106699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10684f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 10694f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 10704f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 10714f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 107299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1074faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 1075faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1076948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 1077faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 1078d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 1079d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 1080faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 108143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 1082faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1083faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1084948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 1085faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1086faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1087948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 1088948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 1089948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 10900a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // Hardware vsync is not currently available, so abort the resync 10910a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // attempt for now 1092948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 1093948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1094948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 10959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 10969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 1097faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1098faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 1099faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 1100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 1102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 1103d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 1104d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 1105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 1106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1109948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 1110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 1112d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 1113d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 1114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 1115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 1116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1117948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 1118948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 1119948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1120faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1121faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 11224a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() { 11234a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray static constexpr nsecs_t kIgnoreDelay = ms2ns(500); 112457164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza 112557164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza // No explicit locking is needed here since EventThread holds a lock while calling this method 112657164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza static nsecs_t sLastResyncAttempted = 0; 112757164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza const nsecs_t now = systemTime(); 112857164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza if (now - sLastResyncAttempted > kIgnoreDelay) { 11290a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza resyncToHardwareVsync(false); 11304a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray } 113157164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza sLastResyncAttempted = now; 11324a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray} 11334a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 11343cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type, 11353cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas nsecs_t timestamp) { 11363cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas Mutex::Autolock lock(mStateLock); 11373cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas // Ignore any vsyncs from the non-active hardware composer. 11383cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas if (composer != mHwc) { 11393cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas return; 11403cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } 11413cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas 1142d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 1143faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1144d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 1145d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1146d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 1147d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 1148faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1149148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 1150d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 1151d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 1152d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 1153d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 1154d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 1155d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 1156148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 1157148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 11580a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { 1159d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson std::lock_guard<std::mutex> lock(mCompositorTimingLock); 11600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson *compositorTiming = mCompositorTiming; 11610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson} 11620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 11637d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::createDefaultDisplayDevice() { 11647d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const int32_t type = DisplayDevice::DISPLAY_PRIMARY; 11657d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk wp<IBinder> token = mBuiltinDisplays[type]; 11665d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 11677d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // All non-virtual displays are currently considered secure. 11687d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const bool isSecure = true; 11697d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 11707d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<IGraphicBufferProducer> producer; 11717d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<IGraphicBufferConsumer> consumer; 11727d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk BufferQueue::createBufferQueue(&producer, &consumer); 11735576a555a14edd8c76addce2cee37b9b9ced2c3fStephen Kiazyk 11747d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer); 117580c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko 11767d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk bool hasWideColorModes = false; 11777d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type); 11787d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk for (android_color_mode_t colorMode : modes) { 11797d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk switch (colorMode) { 11807d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk case HAL_COLOR_MODE_DISPLAY_P3: 11817d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk case HAL_COLOR_MODE_ADOBE_RGB: 11827d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk case HAL_COLOR_MODE_DCI_P3: 11837d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk hasWideColorModes = true; 11847d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk break; 11857d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk default: 11867d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk break; 118780c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko } 11887d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk } 11897d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure, 11907d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk token, fbs, producer, mRenderEngine->getEGLConfig(), 11917d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk hasWideColorModes && hasWideColorDisplay); 11927d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mDisplays.add(token, hw); 11937d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE; 11947d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if (hasWideColorModes && hasWideColorDisplay) { 11957d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk defaultColorMode = HAL_COLOR_MODE_SRGB; 11967d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk } 11977d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk setActiveColorModeInternal(hw, defaultColorMode); 11987d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk} 11998d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk 12007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) { 12017d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false"); 12028722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk 12037d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if (composer->isUsingVrComposer()) { 12047d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // We handle initializing the primary display device for the VR 12057d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // window manager hwc explicitly at the time of transition. 12067d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if (disp != DisplayDevice::DISPLAY_PRIMARY) { 12077d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk ALOGE("External displays are not supported by the vr hardware composer."); 12087d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk } 12097d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk return; 12107d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk } 12117d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 12127d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if (disp == DisplayDevice::DISPLAY_PRIMARY) { 12137d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk Mutex::Autolock lock(mStateLock); 12147d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY); 12157d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk createDefaultDisplayDevice(); 12169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 12179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto type = DisplayDevice::DISPLAY_EXTERNAL; 12189e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 1219692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 12209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(type); 12219e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 1222692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 1223692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 12249e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 12259e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 12269e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 12279e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 12283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 12298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 12308630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 12313cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onInvalidateReceived(HWComposer* composer) { 12323cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas Mutex::Autolock lock(mStateLock); 12333cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas if (composer == mHwc) { 12343cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas repaintEverything(); 12353cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } else { 12363cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas // This isn't from our current hardware composer. If it's a callback 12373cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas // from the real composer, forward the refresh request to vr 12383cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas // flinger. Otherwise ignore it. 12393cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas if (!composer->isUsingVrComposer()) { 12403cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas mVrFlinger->OnHardwareComposerRefresh(); 12413cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } 12423cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } 12433cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas} 12443cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas 12459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) { 1246faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 12479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza getHwComposer().setVsyncEnabled(disp, 12489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); 12498630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 12508630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 125187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::clearHwcLayers(const LayerVector& layers) { 125287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar for (size_t i = 0; i < layers.size(); ++i) { 125387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar layers[i]->clearHwcLayers(); 125487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar } 125587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar} 125687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 12577d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk// Note: it is assumed the caller holds |mStateLock| when this is called 12587d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazykvoid SurfaceFlinger::resetHwcLocked() { 125987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar disableHardwareVsync(true); 126087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar clearHwcLayers(mDrawingState.layersSortedByZ); 126187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar clearHwcLayers(mCurrentState.layersSortedByZ); 126287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // Clear the drawing state so that the logic inside of 126387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // handleTransactionLocked will fire. It will determine the delta between 126487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // mCurrentState and mDrawingState and re-apply all changes when we make the 126587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // transition. 126687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar mDrawingState.displays.clear(); 1267da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk // Release virtual display hwcId during vr mode transition. 1268da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1269da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1270da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk if (displayDevice->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL) { 1271da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk displayDevice->disconnect(getHwComposer()); 1272da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk } 1273da8490da6221ba2a8762fa04f863bddb4088d587Alex Sakhartchouk } 127487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar mDisplays.clear(); 127587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar} 127687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 1277050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid SurfaceFlinger::updateVrFlinger() { 1278050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (!mVrFlinger) 1279050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return; 1280050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay; 1281050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) { 1282209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus return; 1283209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus } 12847d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 1285050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (vrFlingerRequestsDisplay && !mVrHwc) { 1286209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus // Construct new HWComposer without holding any locks. 1287209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus mVrHwc = new HWComposer(true); 12887d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 12897d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // Set up the event handlers. This step is neccessary to initialize the internal state of 12907d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // the hardware composer object properly. Our callbacks are designed such that if they are 12917d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // triggered between now and the point where the display is properly re-initialized, they 12927d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // will not have any effect, so this is safe to do here, before the lock is aquired. 12937d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this)); 1294209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus ALOGV("Vr HWC created"); 1295209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus } 129687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 12977d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk Mutex::Autolock _l(mStateLock); 129887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 12997d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if (vrFlingerRequestsDisplay) { 13007d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk resetHwcLocked(); 130187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 13027d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mHwc = mVrHwc; 13037d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVrFlinger->GrantDisplayOwnership(); 130487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 13057d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk } else { 13067d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVrFlinger->SeizeDisplayOwnership(); 130787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 13087d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk resetHwcLocked(); 13097d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 13107d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mHwc = mRealHwc; 13117d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk enableHardwareVsync(); 131287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar } 13137d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 13147d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVisibleRegionsDirty = true; 13157d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk invalidateHwcGeometry(); 13167d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 13177d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // Explicitly re-initialize the primary display. This is because some other 13187d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // parts of this class rely on the primary display always being available. 13197d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk createDefaultDisplayDevice(); 13207d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 132182386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk // Reset the timing values to account for the period of the swapped in HWC 132282386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 132382386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk const nsecs_t period = activeConfig->getVsyncPeriod(); 132482386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk mAnimFrameTracker.setDisplayRefreshPeriod(period); 132582386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk setCompositorTimingSnapped(0, period, 0); 132682386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk 13277d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk android_atomic_or(1, &mRepaintEverything); 13287d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk setTransactionFlags(eDisplayTransactionNeeded); 132987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar} 133087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 13314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 13321c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 133399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 13346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 13355018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza bool frameMissed = !mHadClientComposition && 13365018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence != Fence::NO_FENCE && 13370a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson (mPreviousPresentFence->getSignalTime() == 13380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson Fence::SIGNAL_TIME_PENDING); 13395018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); 1340c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza if (mPropagateBackpressure && frameMissed) { 1341af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard ALOGD("Backpressure trigger, skipping transaction & refresh!"); 13425018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza signalLayerUpdate(); 13435018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza break; 13445018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza } 13455018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza 1346050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Now that we're going to make it to the handleMessageTransaction() 1347050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // call below it's safe to call updateVrFlinger(), which will 1348050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // potentially trigger a display handoff. 1349050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas updateVrFlinger(); 1350050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 13516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 13526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 13535878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 13546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 13555878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 13565878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 13575878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 13586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 13596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 13606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 13616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 13626b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 13636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 13646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 13656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 13664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13696b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 1370c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard uint32_t transactionFlags = peekTransactionFlags(); 13714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 137287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 13736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 13744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13756b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 13764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13786b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 1379cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 13806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 13814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 13823a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 13834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 1384cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 138514cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 138640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 138705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 1388d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson preComposition(refreshStartTime); 138905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza rebuildLayerStacks(); 139005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza setUpHWComposer(); 139105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doDebugFlashRegions(); 139205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doComposition(); 13930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson postComposition(refreshStartTime); 139405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 139511d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 1396bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza 1397bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = false; 1398bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1399bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1400bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = mHadClientComposition || 1401bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); 1402bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza } 140314cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.clear(); 1405cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1406cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1407cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 1408cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 1409cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 1410cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 1411cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 1412cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1413cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 1414cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1415cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 14162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1417cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1418cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1419cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 1420cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 1421cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 1422cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1423cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 1424cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 14253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 14263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 14273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1428da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1429cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1430cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1431cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1432cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1433cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 1434cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1435cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 1436cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 1437cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1438bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 14399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14407bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 14417bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 14427bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 14437bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 14447bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 14457bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 14469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 14479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 1448bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 1449cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1450cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1451d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime) 1452cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 14539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 14549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("preComposition"); 14559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1456cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 14572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 14582047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (layer->onPreComposition(refreshStartTime)) { 1459cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 1460cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 14612047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 14622047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 1463cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 1464cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 1465cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1466cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1467a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 14680a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::updateCompositorTiming( 14690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime, 14700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson std::shared_ptr<FenceTime>& presentFenceTime) { 14710a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Update queue of past composite+present times and determine the 14720a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // most recently known composite to present latency. 14730a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson mCompositePresentTimes.push({compositeTime, presentFenceTime}); 14740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t compositeToPresentLatency = -1; 14750a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson while (!mCompositePresentTimes.empty()) { 14760a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson CompositePresentTime& cpt = mCompositePresentTimes.front(); 14770a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Cached values should have been updated before calling this method, 14780a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // which helps avoid duplicate syscalls. 14790a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t displayTime = cpt.display->getCachedSignalTime(); 14800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson if (displayTime == Fence::SIGNAL_TIME_PENDING) { 14810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson break; 14820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 14830a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson compositeToPresentLatency = displayTime - cpt.composite; 14840a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson mCompositePresentTimes.pop(); 14850a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 14860a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 14870a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Don't let mCompositePresentTimes grow unbounded, just in case. 14880a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson while (mCompositePresentTimes.size() > 16) { 14890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson mCompositePresentTimes.pop(); 14900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 14910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1492d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson setCompositorTimingSnapped( 1493d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson vsyncPhase, vsyncInterval, compositeToPresentLatency); 1494d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson} 1495d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson 1496d001058145c2186f454a3fb043388d6d9b84c9d8Brian Andersonvoid SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, 1497d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { 14980a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Integer division and modulo round toward 0 not -inf, so we need to 14990a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // treat negative and positive offsets differently. 1500d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? 15010a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : 15020a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson ((-sfVsyncPhaseOffsetNs) % vsyncInterval); 15030a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1504d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. 1505d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson if (idealLatency <= 0) { 1506d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson idealLatency = vsyncInterval; 1507d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson } 1508d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson 15090a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Snap the latency to a value that removes scheduling jitter from the 15100a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // composition and present times, which often have >1ms of jitter. 15110a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Reducing jitter is important if an app attempts to extrapolate 15120a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // something (such as user input) to an accurate diasplay time. 15130a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs 15140a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // with (presentLatency % interval). 1515d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t bias = vsyncInterval / 2; 1516d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson int64_t extraVsyncs = 1517d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; 1518d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? 1519d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; 15200a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1521d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson std::lock_guard<std::mutex> lock(mCompositorTimingLock); 15220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson mCompositorTiming.deadline = vsyncPhase - idealLatency; 15230a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson mCompositorTiming.interval = vsyncInterval; 1524d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; 15250a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson} 15260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 15270a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime) 1528cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 15299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 15309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postComposition"); 15319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 15323546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson // Release any buffers which were replaced this frame 1533f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson nsecs_t dequeueReadyTime = systemTime(); 15343546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson for (auto& layer : mLayersWithQueuedFrames) { 1535f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson layer->releasePendingBuffer(dequeueReadyTime); 15363546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson } 15373546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson 15387d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 15397d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked()); 15403d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 15413d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::shared_ptr<FenceTime> glCompositionDoneFenceTime; 15423d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) { 15433d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = 15443d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::make_shared<FenceTime>(hw->getClientTargetAcquireFence()); 15453d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); 15463d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } else { 15473d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = FenceTime::NO_FENCE; 15483d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } 15493d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mGlCompositionDoneTimeline.updateSignalTimes(); 15503d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 15514e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 15524e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson auto presentFenceTime = std::make_shared<FenceTime>(presentFence); 15534e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson mDisplayTimeline.push(presentFenceTime); 15543d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mDisplayTimeline.updateSignalTimes(); 15553d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 15560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0); 15570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod(); 15580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 15590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // We use the refreshStartTime which might be sampled a little later than 15600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // when we started doing work for this frame, but that should be okay 15610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // since updateCompositorTiming has snapping logic. 15620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson updateCompositorTiming( 15634e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime); 1564d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson CompositorTiming compositorTiming; 1565d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson { 1566d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson std::lock_guard<std::mutex> lock(mCompositorTimingLock); 1567d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson compositorTiming = mCompositorTiming; 1568d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson } 15690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 15702047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 15712047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, 15724e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson presentFenceTime, compositorTiming); 1573e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (frameLatched) { 15742047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr recordBufferingStats(layer->getName().string(), 15752047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->getOccupancyHistory(false)); 1576e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 15772047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 15784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 15794e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson if (presentFence->isValid()) { 15804e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson if (mPrimaryDispSync.addPresentFence(presentFence)) { 1581faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1582faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1583948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1584faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1585faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1586faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1587cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard if (!hasSyncFramework) { 15882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1589faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1590faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1591faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1592faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 15934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 15944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 15954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 15964e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson if (presentFenceTime->isValid()) { 15973d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mAnimFrameTracker.setActualPresentFence( 15984e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson std::move(presentFenceTime)); 15994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 16004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 16014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 16029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nsecs_t presentTime = 16039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 16044b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 16054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 16064b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 16074b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1608b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1609b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1610b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1611b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1612b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1613b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1614b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1615b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1616b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1617b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t elapsedTime = currentTime - mLastSwapTime; 16180a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval); 1619b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (numPeriods < NUM_BUCKETS - 1) { 1620b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[numPeriods] += elapsedTime; 1621b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1622b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; 1623b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1624b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime += elapsedTime; 1625b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1626b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime = currentTime; 1627cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1628cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1629cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 16309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 16319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("rebuildLayerStacks"); 16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1633cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 1634764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1635764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey ATRACE_CALL(); 1636764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey mVisibleRegionsDirty = false; 1637764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey invalidateHwcGeometry(); 1638ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 1639764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1640764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region opaqueRegion; 1641764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region dirtyRegion; 1642764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Vector<sp<Layer>> layersSortedByZ; 1643764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const sp<DisplayDevice>& displayDevice(mDisplays[dpy]); 1644764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const Transform& tr(displayDevice->getTransform()); 1645764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const Rect bounds(displayDevice->getBounds()); 1646764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (displayDevice->isDisplayOn()) { 1647764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey computeVisibleRegions( 1648764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->getLayerStack(), dirtyRegion, 1649764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey opaqueRegion); 1650764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey 1651764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey mDrawingState.traverseInZOrder([&](Layer* layer) { 1652764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (layer->getLayerStack() == displayDevice->getLayerStack()) { 1653764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region drawRegion(tr.transform( 1654764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey layer->visibleNonTransparentRegion)); 1655764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey drawRegion.andSelf(bounds); 1656764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (!drawRegion.isEmpty()) { 1657764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey layersSortedByZ.add(layer); 1658764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } else { 1659764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey // Clear out the HWC layer if this layer was 1660764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey // previously visible, but no longer is 1661764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey layer->setHwcLayer(displayDevice->getHwcDisplayId(), 1662764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey nullptr); 1663764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } 166406a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard } else { 16658226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // WM changes displayDevice->layerStack upon sleep/awake. 16668226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // Here we make sure we delete the HWC layers even if 16678226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // WM changed their layer stack. 166806a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard layer->setHwcLayer(displayDevice->getHwcDisplayId(), 166906a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard nullptr); 167087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1671764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey }); 1672764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } 1673764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); 1674764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->undefinedRegion.set(bounds); 1675764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->undefinedRegion.subtractSelf( 1676764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey tr.transform(opaqueRegion)); 1677764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->dirtyRegion.orSelf(dirtyRegion); 16783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 16793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1680cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 16813b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 16825d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// pickColorMode translates a given dataspace into the best available color mode. 16835d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// Currently only support sRGB and Display-P3. 16845d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) { 16855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter switch (dataSpace) { 16865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter // treat Unknown as regular SRGB buffer, since that's what the rest of the 16875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter // system expects. 16885d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter case HAL_DATASPACE_UNKNOWN: 16895d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter case HAL_DATASPACE_SRGB: 16905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter case HAL_DATASPACE_V0_SRGB: 16915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter return HAL_COLOR_MODE_SRGB; 16925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter break; 16935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 16945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter case HAL_DATASPACE_DISPLAY_P3: 16955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter return HAL_COLOR_MODE_DISPLAY_P3; 16965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter break; 16975d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 16985d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter default: 16995d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter // TODO (courtneygo): Do we want to assert an error here? 17005d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGE("No color mode mapping for %s (%#x)", dataspaceDetails(dataSpace).c_str(), 17015d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter dataSpace); 17025d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter return HAL_COLOR_MODE_SRGB; 17035d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter break; 17045d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter } 17055d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter} 17065d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 17075d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_dataspace SurfaceFlinger::bestTargetDataSpace(android_dataspace a, android_dataspace b) { 17085d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter // Only support sRGB and Display-P3 right now. 17095d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) { 17105d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter return HAL_DATASPACE_DISPLAY_P3; 17115d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter } 17125d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter return HAL_DATASPACE_V0_SRGB; 17135d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter} 17145d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 1715cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 17169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 17179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("setUpHWComposer"); 17189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1719028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1720b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1721b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1722b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1723b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1724b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1725b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1726b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1727b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1728b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1729b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1730b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1731b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1732b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1733b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1734b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1735b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1736b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1737b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1738b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1739b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1740b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 17417143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1742b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1743b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1744b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1745b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1746028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1747028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 17489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // build the h/w work list 17499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (CC_UNLIKELY(mGeometryInvalid)) { 17509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = false; 17519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 17529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<const DisplayDevice> displayDevice(mDisplays[dpy]); 17539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 17549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 17559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Vector<sp<Layer>>& currentLayers( 17569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getVisibleLayersSortedByZ()); 1757ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr for (size_t i = 0; i < currentLayers.size(); i++) { 17581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const auto& layer = currentLayers[i]; 17599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!layer->hasHwcLayer(hwcId)) { 17609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = mHwc->createLayer(hwcId); 17619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcLayer) { 17629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(hwcId, std::move(hwcLayer)); 17639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 17649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 17659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 1766a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1767a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1768a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1769ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr layer->setGeometry(displayDevice, i); 17709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (mDebugDisableHWC || mDebugRegion) { 17719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 177203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 177303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 177403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 177503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 17769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 177703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 17789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 17799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 17809f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 17819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Set the per-frame data 17829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 17839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 17849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 17855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 17869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId < 0) { 17879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 17889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 17899f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (colorMatrix != mPreviousColorMatrix) { 17909f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza status_t result = mHwc->setColorTransform(hwcId, colorMatrix); 17919f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " 17929f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza "display %zd: %d", displayId, result); 17939f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 17949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 17959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setPerFrameData(displayDevice); 179638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 17975d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 17985d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter if (hasWideColorDisplay) { 17995d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter android_color_mode newColorMode; 18005d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB; 18015d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 18025d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 18035d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace); 18045d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)", 18055d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(), 18065d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace); 18075d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter } 18085d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter newColorMode = pickColorMode(newDataSpace); 18095d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 18105d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter setActiveColorModeInternal(displayDevice, newColorMode); 18115d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter } 181252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 18139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 18149f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mPreviousColorMatrix = colorMatrix; 18159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 18169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 18177bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 18187bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 18197bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 18207bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 18217bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 18227bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 18239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 18249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 18259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 182752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1828cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 18309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposition"); 18319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 183252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 183392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 18344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 18352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1836cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 183802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 183902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 184002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 184102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 184587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 18464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 184752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1852841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 18539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postFramebuffer"); 1854b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1855a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1856a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1857c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 18589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 18599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 18607bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 18617bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 18627bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 18639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 18649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 1865a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard mHwc->presentAndGetReleaseFences(hwcId); 18669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 18672dc3be88bd85791556ab0e6df6a080989886749eDan Stoza displayDevice->onSwapBuffersCompleted(); 1868b2c838b7add20c4515966a80de809b0a1d315001Season Li displayDevice->makeCurrent(mEGLDisplay, mEGLContext); 18699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 18709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> releaseFence = Fence::NO_FENCE; 18719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) { 18729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = displayDevice->getClientTargetAcquireFence(); 18739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 18749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = layer->getHwcLayer(hwcId); 18759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer); 187652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 18779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->onLayerDisplayed(releaseFence); 18789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 18799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 18809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->clearReleaseFences(hwcId); 1881ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1882e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1883e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1884a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1885a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 18866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 18877d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 18887d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount(); 18896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 18906547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 18916547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 189487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1896841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1897841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 18987cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 18997cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 19007cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 19017cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 19027cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 19037cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1904ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1905ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1906ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1907ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1908ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1909ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1910ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1911ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1912ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1913ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1914e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 191587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1916ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1917ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1918ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1919ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1920ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 19213d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 19243d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 19257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // Notify all layers of available frames 19262047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([](Layer* layer) { 19272047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->notifyAvailableFrames(); 19282047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 19297dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 19362047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 19382047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (!trFlags) return; 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 19432047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 19473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1950e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 195192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 195292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 195392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 195692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 195892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 195993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 196092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 196192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 196292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 196392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 196492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 196592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1966e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1967e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 196892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 19693ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 197027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 197127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 197227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 19737d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked()); 1974875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 19757d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i))); 197602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 197702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 19789e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 19797adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 198002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 198192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 198292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 198392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 198492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 198592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 19873ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1988097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1989097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 19901474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1991e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 199293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 199393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 199493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 19957d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<DisplayDevice> hw(getDisplayDeviceLocked(display)); 199602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 199702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 199893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 199993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 200093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 200193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 200293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 200392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 200493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 20057d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const sp<DisplayDevice> disp(getDisplayDeviceLocked(display)); 200693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 200793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 200893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 200993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 201000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 201100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 201200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 201300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 201400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 20154fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 201693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 201747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 201847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 201947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 202092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 202192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 202292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 202392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 202492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 202592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 202692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 2027e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 2028e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 2029cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 203099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 2031db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 2032b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 2033b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 20340556d79eacbf0c9978080d87aa4075120533c7efMathias Agopian BufferQueue::createBufferQueue(&bqProducer, &bqConsumer); 2035db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 20369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t hwcId = -1; 203799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 203802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 203902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 204002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 204199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 2042db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 20435cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk // Allow VR composer to use virtual displays. 20445cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk if (mUseHwcVirtualDisplays || mHwc == mVrHwc) { 20458cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int width = 0; 20468cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int status = state.surface->query( 20478cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_WIDTH, &width); 20488cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 20498cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query width (%d)", status); 20508cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int height = 0; 20518cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 20528cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_HEIGHT, &height); 20538cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 20548cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query height (%d)", status); 20558cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int intFormat = 0; 20568cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 20578cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_FORMAT, &intFormat); 20588cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 20598cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query format (%d)", status); 20608cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza auto format = static_cast<android_pixel_format_t>( 20618cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza intFormat); 20628cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 20638cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mHwc->allocateVirtualDisplay(width, height, &format, 20648cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza &hwcId); 20658cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 20669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 20675cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza // TODO: Plumb requested format back up to consumer 20685cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza 20699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VirtualDisplaySurface> vds = 20709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new VirtualDisplaySurface(*mHwc, 20719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId, state.surface, bqProducer, 20729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer, state.displayName); 2073db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 2074db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 207547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 207699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 207799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 2078cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 2079cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 2080cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 2081cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 208287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 208387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar hwcId = state.type; 208487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer); 208587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar producer = bqProducer; 2086cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2087cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 2088cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 208999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 20905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter sp<DisplayDevice> hw = 20915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter new DisplayDevice(this, state.type, hwcId, state.isSecure, display, 20925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter dispSurface, producer, 20935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter mRenderEngine->getEGLConfig(), 20945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter hasWideColorDisplay); 2095cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 2096cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 20974fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 20988dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 2099cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 21009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!state.isVirtualDisplay()) { 21017adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 21021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 210393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 210492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 210592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 2106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 21073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 2108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 21108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 21118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 21128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 21138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 21148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 21158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 21168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 21178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 21188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 21198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 21208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 21218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 21228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 21238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 21248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 21258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 21268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 21278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 21288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 21298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 21308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 21312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool first = true; 21322047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 21338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 21348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 21358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 21361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr uint32_t layerStack = layer->getLayerStack(); 21372047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (first || currentlayerStack != layerStack) { 21388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 21398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 21408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 21418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 21428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 21438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 21448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 21458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 21468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 21478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 21488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 214991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 21508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 21518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 21528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 21538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 21548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 215591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 215691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 215791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 215891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 215991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 216091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 216191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 21627d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk disp = getDefaultDisplayDeviceLocked(); 21638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 216491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 21652047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 21662047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr first = false; 21672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 21688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 21698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 21708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 21713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 21723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 21733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 21741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 21751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mLayersAdded) { 21761f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersAdded = false; 21771f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // Layers have been added. 21783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 21793559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 21803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 21813559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 21823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 21833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 21843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 21853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 21862047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 21871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mLayersPendingRemoval.indexOf(layer) >= 0) { 21883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 21893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 21903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 21913559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 21921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Region visibleReg; 21931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr visibleReg.set(layer->computeScreenBounds()); 21941f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr invalidateLayerStack(layer->getLayerStack(), visibleReg); 21950aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 21962047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 220003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 220103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 220203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 220303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 220403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 220503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 22069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 22089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getHwcDisplayId() < 0) { 220903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 221003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 22119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 22129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 22139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->updateCursorPosition(displayDevice); 221403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 221503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 22164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 22174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 22184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 22194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 2220598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (!mLayersPendingRemoval.isEmpty()) { 22214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 22221f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr for (const auto& l : mLayersPendingRemoval) { 22231f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr recordBufferingStats(l->getName().string(), 22241f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr l->getOccupancyHistory(true)); 22251f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr l->onRemoved(); 22264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 22274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 22284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 22294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 22304b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 22314b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 22324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 22334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 22344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 22351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mDrawingState.traverseInZOrder([](Layer* layer) { 22361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->commitChildList(); 22371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 22382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 22392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 22404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22432047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack, 224487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 2245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2246841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 22479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("computeVisibleRegions"); 2248841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 2249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 2250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 2252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 225387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22552047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInReverseZOrder([&](Layer* layer) { 2256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 22571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 225901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 22601f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (layer->getLayerStack() != layerStack) 22612047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr return; 226287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2263ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2264ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 2265ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 2267ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2268ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2269ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 2270ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 2271ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 2272ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 2273ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 2275ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2276ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2277ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 2278ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 2279ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 2281ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2282a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 2283a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 2284a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 2285a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 2286a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 2287a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 2288a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 2289a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 2290a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 2291a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 2292ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2293ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 2294da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 22954125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 22961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Rect bounds(layer->computeScreenBounds()); 2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 22981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Transform tr = layer->getTransform(); 2299ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 2300ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 2301ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 230222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza if (tr.preserveRects()) { 230322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transform the transparent region 230422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion = tr.transform(s.activeTransparentRegion); 23054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 230622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transformation too complex, can't do the 230722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transparent region optimization. 230822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion.clear(); 23094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 2310ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2312ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 23131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const int32_t layerOrientation = tr.getOrientation(); 23149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.alpha == 1.0f && !translucent && 2315ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 2316ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 2317ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 2318ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2322ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 2323ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 2324ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2325ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 2326ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 2327ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 2334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 23364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 2338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2339a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 2340ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 2341ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 2342ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 2343ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2344ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 2345ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 2346ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 2347ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2348ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 2349ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 2350a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 2351ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 23524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 23534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 2354ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 2355ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 2356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 2358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 236087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 2361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2362ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 2363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 23648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2365a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 2367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 2368a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 2369a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 23702047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 237287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 237587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 237687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 237792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 23784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 23794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 23804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 238192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 238292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 238387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 238487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 23856b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 2386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 23879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("handlePageFlip"); 23889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 2389d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson nsecs_t latchTime = systemTime(); 239099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 23914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 23926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 23930cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan bool newDataLatched = false; 239451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 239551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 239651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 239751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 239851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 239951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 240051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 240151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 240251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 240351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 24042047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 24056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 24066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 24076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 24082047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mLayersWithQueuedFrames.push_back(layer); 2409ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2410ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 24116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 2412ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2413ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 24146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 24152047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 24162047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 24179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 2418d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const Region dirty(layer->latchBuffer(visibleRegions, latchTime)); 2419ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 24201f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr invalidateLayerStack(layer->getLayerStack(), dirty); 24210cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan if (!dirty.isEmpty()) { 24220cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan newDataLatched = true; 24230cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan } 24244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 24254da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 24263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 24276b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 24286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 24296b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 24306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 24319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (frameQueued && mLayersWithQueuedFrames.empty()) { 24326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 24336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 24346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 24356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 24360cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan return !mLayersWithQueuedFrames.empty() && newDataLatched; 2437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2439ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 2440ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 24419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = true; 2442ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 2443ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 244499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2445830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition( 2446830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const sp<const DisplayDevice>& displayDevice, 244787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 2448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24497143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 24507143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 24517143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 24527143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 2453830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0; 24547143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 24559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Skipping display composition"); 24567143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 24577143316af216fa92c31a60d4407b707637382da1Dan Stoza } 24587143316af216fa92c31a60d4407b707637382da1Dan Stoza 24599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doDisplayComposition"); 24609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 246187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 246287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2463b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 2464830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion.orSelf(dirtyRegion); 2465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2466830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard uint32_t flags = displayDevice->getFlags(); 24670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 246829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 246929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 247029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 2471830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->swapRegion.bounds()); 2472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 24730f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 247429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 2475df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 247695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 24770f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 2478830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->swapRegion.bounds()); 2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 248029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 2481830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->bounds()); 2482830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion = dirtyRegion; 2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2486830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard if (!doComposeSurfaces(displayDevice, dirtyRegion)) return; 2487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24889c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 2489830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion.orSelf(dirtyRegion); 2490da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 2491da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 2492830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapBuffers(getHwComposer()); 2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces( 24969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<const DisplayDevice>& displayDevice, const Region& dirty) 2497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposeSurfaces"); 24999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 25009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 25019f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 25029f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 oldColorMatrix; 25039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) && 25049f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform); 25059f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 25069f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 25079f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); 25089f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 25099f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 25109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool hasClientComposition = mHwc->hasClientComposition(hwcId); 25119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasClientComposition) { 25129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("hasClientComposition"); 2513a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 25145d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#ifdef USE_HWC2 25155d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter mRenderEngine->setColorMode(displayDevice->getActiveColorMode()); 25165d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter mRenderEngine->setWideColor(displayDevice->getWideColorSupport()); 25175d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#endif 25189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) { 2519c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 25209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getDisplayName().string()); 25213f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 25227d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 25237d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 25247d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) { 25253f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 25263f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 25273f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 2528c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 2529a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2530a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 25319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId); 25329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasDeviceComposition) { 2533b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 2534b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 2535b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 25363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 2537b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 25389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->clearWithColor(0, 0, 0, 0); 2539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 2540766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 25419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region bounds(displayDevice->getBounds()); 2542766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2543766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 2544766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 2545766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 25469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region letterbox(bounds.subtract(displayDevice->getScissor())); 2547766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2548766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 25499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Region region(displayDevice->undefinedRegion.merge(letterbox)); 2550766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2551766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 2552766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 2553766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2554b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 255587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 2556b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 25579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza drawWormhole(displayDevice, region); 2558b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 2559a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 2560f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 25619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 2562766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 2563f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 2564f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 25659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& bounds(displayDevice->getBounds()); 25669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& scissor(displayDevice->getScissor()); 2567f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 2568f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 2569f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 2570f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 25713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2572f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 25739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const uint32_t height = displayDevice->getHeight(); 25749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->setScissor(scissor.left, height - scissor.bottom, 25753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 2576f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 2577f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 257885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 25794b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 258085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 258185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 258285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 25834b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 25849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Rendering client layers"); 25859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& displayTransform = displayDevice->getTransform(); 25869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 258785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 25889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool firstLayer = true; 25899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 25909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region clip(dirty.intersect( 25919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 25929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Layer: %s", layer->getName().string()); 25939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Composition type: %s", 25949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza to_string(layer->getCompositionType(hwcId)).c_str()); 259585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 25969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza switch (layer->getCompositionType(hwcId)) { 25979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Cursor: 25989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Device: 2599267ab79b22f9d0b995ff787e36aca9c39497c489Gray Huang case HWC2::Composition::Sideband: 26009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::SolidColor: { 2601ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 26029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getClearClientTarget(hwcId) && !firstLayer && 26039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->isOpaque(state) && (state.alpha == 1.0f) 26049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza && hasClientComposition) { 2605cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 2606cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 26071748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard layer->clearWithOpenGL(displayDevice); 2608cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 260985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 261085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 26119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Client: { 26129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 261385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 2614a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 26159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza default: 2616da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 2617cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 26189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 26199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Skipping for empty clip"); 2620a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 26219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza firstLayer = false; 262285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 262385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 262485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 26259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 262685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 26279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 262885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 26299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 263085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 26314b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 26324b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 2633f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 26349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 26359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza getRenderEngine().setupColorTransform(oldColorMatrix); 26369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 26379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 2638f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 26399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->disableScissor(); 26403f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 2641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2643830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const { 2644830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const int32_t height = displayDevice->getHeight(); 26453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 26463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 2647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26497d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 2650ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 26516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 26521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const sp<Layer>& lbc, 26531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const sp<Layer>& parent) 26541b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 26557d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 26567d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 26577d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 26581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mNumLayers >= MAX_LAYERS) { 26597d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 26607d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 26611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (parent == nullptr) { 26621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.layersSortedByZ.add(lbc); 26631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } else { 2664e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) { 2665e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu ALOGE("addClientLayer called with a removed parent"); 2666e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu return NAME_NOT_FOUND; 2667e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu } 26681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr parent->addChild(lbc); 26691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 2670e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu 26717d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 26721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersAdded = true; 26731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mNumLayers++; 26747d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 26757d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 267696f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 2677ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 26784f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 26797d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 268096f0819f81293076e652792794a961543e6750d7Mathias Agopian} 268196f0819f81293076e652792794a961543e6750d7Mathias Agopian 2682515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wustatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) { 26837f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr Mutex::Autolock _l(mStateLock); 26847f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr 26851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const auto& p = layer->getParent(); 2686515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu ssize_t index; 2687e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu if (p != nullptr) { 2688515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu if (topLevelOnly) { 2689515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu return NO_ERROR; 2690515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu } 2691515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu 2692e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu sp<Layer> ancestor = p; 2693e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu while (ancestor->getParent() != nullptr) { 2694e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu ancestor = ancestor->getParent(); 2695e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu } 2696e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) { 2697e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu ALOGE("removeLayer called with a layer whose parent has been removed"); 2698e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu return NAME_NOT_FOUND; 2699e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu } 2700fae51c438827ae0a55c1b83c0e9be348254bfbd4Chia-I Wu 2701fae51c438827ae0a55c1b83c0e9be348254bfbd4Chia-I Wu index = p->removeChild(layer); 2702515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu } else { 2703515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu index = mCurrentState.layersSortedByZ.remove(layer); 2704e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu } 2705e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu 2706136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // As a matter of normal operation, the LayerCleaner will produce a second 2707136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // attempt to remove the surface. The Layer will be kept alive in mDrawingState 2708136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // so we will succeed in promoting it, but it's already been removed 2709136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // from mCurrentState. As long as we can find it in mDrawingState we have no problem 2710136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // otherwise something has gone wrong and we are leaking the layer. 2711136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) { 27121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ALOGE("Failed to find layer (%s) in layer parent (%s).", 27131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->getName().string(), 27141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr (p != nullptr) ? p->getName().string() : "no-parent"); 27151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return BAD_VALUE; 2716136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr } else if (index < 0) { 2717136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr return NO_ERROR; 2718598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch } 27191f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 27201f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersPendingRemoval.add(layer); 27211f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersRemoved = true; 2722e6b63e1ae12692327f7e46d5f10d6ade5a7bf192Chia-I Wu mNumLayers -= 1 + layer->getChildrenCount(); 27231f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr setTransactionFlags(eTransactionNeeded); 27241f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return NO_ERROR; 2725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2727c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() { 2728dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 2729dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 2730dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 27313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 2732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 2737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 273899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27438b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 27448b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 27458b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 27468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 27478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 27487c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2749698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 275028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2751e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 27522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 27532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 27542d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 27552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 27567c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 27572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 27582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 27597c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 27607c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 27617c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 27622d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 27632d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 27642d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 27652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 27662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 27672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2768e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2769e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2770e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2771e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2772b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2773b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2774e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2775698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2776698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2777d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2778d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2779d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2780d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2781d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2782d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2783d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2784d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2785097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2786d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 27872ae83f4f628d4da96f363d0668380ba1f753b867Fabien Sanglard if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) { 2788d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2789d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2790d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2791d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2792d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2793698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2794386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 27952a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // If a synchronous transaction is explicitly requested without any changes, 27962a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // force a transaction anyway. This can be used as a flush mechanism for 27972a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // previous async transactions. 27982a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr if (transactionFlags == 0 && (flags & eSynchronous)) { 27992a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr transactionFlags = eTransactionNeeded; 28002a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr } 28012a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr 280228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2803ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 2804ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags); 2805ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2806468051e20be19130572231266db306396a56402bIrvel 2807386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 280828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2809698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2810386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2811386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2812386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 28132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 28142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 28152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 28162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2817386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 28182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2819386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2820386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2821386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2822386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 28232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 28242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2825386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2826386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2827cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 28339a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 28349a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 28359a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 28369a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 28389a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 28393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2842097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2852e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 285300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 286747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 286847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 286947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 287047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 287147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 287247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 287347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 287447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 287547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 287647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 288613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 288999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr bool geometryAppliesWithResize = 289099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr what & layer_state_t::eGeometryAppliesWithResize; 2891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 289299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) { 2893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 289482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr } 2895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 28981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const auto& p = layer->getParent(); 28991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (p == nullptr) { 29001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 29011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (layer->setLayer(s.z) && idx >= 0) { 29021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.layersSortedByZ.removeAt(idx); 29031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.layersSortedByZ.add(layer); 29041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // we need traversal (state changed) 29051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // AND transaction (list changed) 29061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 29071f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 29081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } else { 29091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (p->setChildLayer(layer, s.z)) { 29101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 29111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 2912e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2913e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2914db66e627ad8904491e384c64f82fc77a939b9705Robert Carr if (what & layer_state_t::eRelativeLayerChanged) { 2915db66e627ad8904491e384c64f82fc77a939b9705Robert Carr if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) { 2916db66e627ad8904491e384c64f82fc77a939b9705Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 2917db66e627ad8904491e384c64f82fc77a939b9705Robert Carr } 2918db66e627ad8904491e384c64f82fc77a939b9705Robert Carr } 2919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2922e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2923e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 29259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->setAlpha(s.alpha)) 2926e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2927e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2928e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2929e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2930e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2931e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2932e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2933e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2934e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2935e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2936231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza if (what & layer_state_t::eFlagsChanged) { 2937e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2939e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2940e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 294199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setCrop(s.crop, !geometryAppliesWithResize)) 2942e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2944acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (what & layer_state_t::eFinalCropChanged) { 29458d5227b8416b099c884429312daf2d60496fa484Robert Carr if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize)) 2946acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos flags |= eTraversalNeeded; 2947acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos } 2948e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2949e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 29501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // We only allow setting layer stacks for top level layers, 29511f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // everything else inherits layer stack from its parent. 29521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (layer->hasParent()) { 29531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid", 29541f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->getName().string()); 29551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } else if (idx < 0) { 29561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ALOGE("Attempt to set layer stack on layer without parent (%s) that " 29571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr "that also does not appear in the top level layer list. Something" 29581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr " has gone wrong.", layer->getName().string()); 29591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } else if (layer->setLayerStack(s.layerStack)) { 2960e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2961e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2962e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2963e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2966e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 29677dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza if (what & layer_state_t::eDeferTransaction) { 29680d48072f6047140119ff194c1194ce402fca2c0bRobert Carr if (s.barrierHandle != nullptr) { 29690d48072f6047140119ff194c1194ce402fca2c0bRobert Carr layer->deferTransactionUntil(s.barrierHandle, s.frameNumber); 29700d48072f6047140119ff194c1194ce402fca2c0bRobert Carr } else if (s.barrierGbp != nullptr) { 29710d48072f6047140119ff194c1194ce402fca2c0bRobert Carr const sp<IGraphicBufferProducer>& gbp = s.barrierGbp; 29720d48072f6047140119ff194c1194ce402fca2c0bRobert Carr if (authenticateSurfaceTextureLocked(gbp)) { 29730d48072f6047140119ff194c1194ce402fca2c0bRobert Carr const auto& otherLayer = 29740d48072f6047140119ff194c1194ce402fca2c0bRobert Carr (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); 29750d48072f6047140119ff194c1194ce402fca2c0bRobert Carr layer->deferTransactionUntil(otherLayer, s.frameNumber); 29760d48072f6047140119ff194c1194ce402fca2c0bRobert Carr } else { 29770d48072f6047140119ff194c1194ce402fca2c0bRobert Carr ALOGE("Attempt to defer transaction to to an" 29780d48072f6047140119ff194c1194ce402fca2c0bRobert Carr " unrecognized GraphicBufferProducer"); 29790d48072f6047140119ff194c1194ce402fca2c0bRobert Carr } 29800d48072f6047140119ff194c1194ce402fca2c0bRobert Carr } 29817dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // We don't trigger a traversal here because if no other state is 29827dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // changed, we don't want this to cause any more work 29837dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 29841db73f66624e7d151710483dd58e03eed672f064Robert Carr if (what & layer_state_t::eReparentChildren) { 29851db73f66624e7d151710483dd58e03eed672f064Robert Carr if (layer->reparentChildren(s.reparentHandle)) { 29861db73f66624e7d151710483dd58e03eed672f064Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 29871db73f66624e7d151710483dd58e03eed672f064Robert Carr } 29881db73f66624e7d151710483dd58e03eed672f064Robert Carr } 29899524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr if (what & layer_state_t::eDetachChildren) { 29909524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr layer->detachChildren(); 29919524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr } 2992c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr if (what & layer_state_t::eOverrideScalingModeChanged) { 2993c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr layer->setOverrideScalingMode(s.overrideScalingMode); 2994c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // We don't trigger a traversal here because if no other state is 2995c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // changed, we don't want this to cause any more work 2996c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr } 2997e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2998e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2999e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3000e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 30014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 30020ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 30030ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 30044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 3005479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle, 3006479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) 3007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 30086e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 3009921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 30106e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 30114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 30126e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 30138b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 30144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 30154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 30164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 30174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 3018bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop String8 uniqueName = getUniqueLayerName(name); 3019bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 30203165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 30213165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 30224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 3023bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName, w, h, flags, format, 30244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 3025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 30263165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 30274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 3028bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName, w, h, flags, 30294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 30304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 30314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 30324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 3033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30367d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 30377d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 3038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 30397d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 3040479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk layer->setInfo(windowType, ownerUid); 3041479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk 30421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr result = addClientLayer(client, *handle, *gbp, layer, *parent); 30437d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 30447d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 30457d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 3046ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceCreation(layer); 30477d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 30487d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 30494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 3050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3052bc7552874052ee33f1b35b4474e20c003d216391Cody NorthropString8 SurfaceFlinger::getUniqueLayerName(const String8& name) 3053bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop{ 3054bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop bool matchFound = true; 3055bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uint32_t dupeCounter = 0; 3056bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3057bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop // Tack on our counter whether there is a hit or not, so everyone gets a tag 3058bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str()); 3059bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3060bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop // Loop over layers until we're sure there is no matching name 3061bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop while (matchFound) { 3062bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop matchFound = false; 3063bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop mDrawingState.traverseInZOrder([&](Layer* layer) { 3064bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop if (layer->getName() == uniqueName) { 3065bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop matchFound = true; 3066bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str()); 3067bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop } 3068bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop }); 3069bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop } 3070bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3071bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop ALOGD_IF(dupeCounter > 0, "duplicate layer name: changing %s to %s", name.c_str(), uniqueName.c_str()); 3072bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3073bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop return uniqueName; 3074bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop} 3075bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 30764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 30774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 30784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 3079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 308192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 3082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 3083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 3084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 3085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 30878f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 3088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 30924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 30934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 30944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 3095b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 3096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 30974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 30984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 30994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 3100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 31034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 31044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 3105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 31064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 31074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 3108b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 31094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 3110118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3111118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3112ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 31139a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 31149524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr // called by a client when it wants to remove a Layer 31156710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 31166710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 31176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 3118ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceDeletion(l); 31196710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 31206710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 31216710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 31229a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 31239a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 31249a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 31259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 312613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 3127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 31286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 31296710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 31309524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr sp<Layer> l = layer.promote(); 31319524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr if (l == nullptr) { 31329524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr // The layer has already been removed, carry on 31339524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr return NO_ERROR; 31349524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr } 3135515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu // If we have a parent, then we can continue to live as long as it does. 3136515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu return removeLayer(l, true); 3137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3139b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 3140b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 314113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 314201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 314313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 314413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 314513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 314601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 314701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 3148692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 314901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 315013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 31514c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 31524c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 315347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 315447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 315513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 315613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 31572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 31586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 31599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 31609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 31616547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 31620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 3163d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Use phase of 0 since phase is not known. 3164d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Use latency of 0, which will snap to the ideal latency. 3165d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson setCompositorTimingSnapped(0, period, 0); 316613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 316713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 316813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 316913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 317013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 317113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 3172c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 317313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 317413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 317513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 317613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 317713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 317813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 317913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 318013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 318113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 31822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 31832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 31842c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 31852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 31862c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 31872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 318813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 31892c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 3190c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 3191c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 3192c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 31932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 31942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 31952c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 31962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 31972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 3198c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 3199ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 3200ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel Mutex::Autolock _l(mStateLock); 3201ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken()); 3202ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (idx < 0) { 3203ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ALOGW("Surface Interceptor SavePowerMode: invalid display token"); 3204ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel return; 3205ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 3206ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); 3207ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 3208ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel 32092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 3210f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn on the display 32112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 3212c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 3213c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 3214c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 3215948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 3216c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 3217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 3219b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 32202c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 3221f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 3222f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 3223f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray param.sched_priority = 1; 3224f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { 3225f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_FIFO on display on"); 3226f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 32272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 3228f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn off the display 3229f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 3230f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { 3231f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_OTHER on display off"); 3232f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 3233f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 3234c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 3235948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 3236948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 3237cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 3238cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 3239cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 3240c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 32412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 32422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 32432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 32442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 32452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 3246b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 3247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 32502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 3251db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 3252db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 32532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 3254b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 32552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 32562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 32572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 3258b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 32592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 3260db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 32612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 32627306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 32639e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 32642c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 32652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 3266db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 32672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 3268db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 3269b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 3270b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 3271b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 32722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 3273db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 3274b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 3275b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 3276b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 3277b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 3278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 3279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 328199b49840d309727678b77403d6cc9f920111623fMathias Agopian 3282bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3283bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 3284bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 3285bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 3286bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 328774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 3288bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 3289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 3290fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 32919795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 32929795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 3293fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 3294fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 32959795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 3296fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 3297fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 3298fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 32999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 33009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 330182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 330282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 330325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 330425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 330525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 330625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 330725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 330874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 330935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 331025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 331125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 331225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 331325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 331482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 331574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 331635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 331782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 331825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 331925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 332025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 332125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 332274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 332335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 332425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 3325c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 3326c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 3327c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 3328c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 3329c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 3330c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 3331c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 3332b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3333b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 3334b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 3335b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 3336b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 3337b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 3338b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 333940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 334040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos if ((index < numArgs) && 3341d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson (args[index] == String16("--frame-events"))) { 334240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos index++; 3343d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson dumpFrameEventsLocked(result); 334440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos dumpAll = false; 334540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos } 3346f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3347f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter if ((index < numArgs) && (args[index] == String16("--wide-color"))) { 3348f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter index++; 3349f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpWideColorInfo(result); 3350f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpAll = false; 3351f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 3352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 33531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 335482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 335574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 335682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 335748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 335882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 335982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 336048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 336182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 336282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 336382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 336482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 336548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 3366c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 3367c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 336825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 33692047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 337074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 33712047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 337225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 337325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 337482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 337574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 337682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 337782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 337882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 337982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 338082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 338182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 338248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 33839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 33849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 338586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 33864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 33874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 3388d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 33894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 33902047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 33914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 3392d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 33934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 33942047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 339582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 339682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 3397ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 339825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 3399c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 340025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 340125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 340225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 340325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 340425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 340525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 340625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 34072047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 340825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 3409d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 341025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 34112047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 34124b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 3413d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 341425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 341525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 34166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 34176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 34186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 34192047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 34206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 34212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 34226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 34236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 34246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 34256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 342663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const 34274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 342863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" [sf"); 3429c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard result.appendFormat(" HAS_CONTEXT_PRIORITY=%d", useContextPriority); 3430c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard 343163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard if (isLayerTripleBufferingDisabled()) 343263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" DISABLE_TRIPLE_BUFFERING"); 3433c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard 3434c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset); 3435a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv); 3436c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize); 3437cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework); 34381971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64, 34391971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard maxFrameBufferAcquiredBuffers); 344063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append("]"); 34414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 34424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 3443b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 3444b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 3445b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 3446b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { 3447b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[b] / 1e9; 3448b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 3449b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[b]) / mTotalTime; 3450b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 3451b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 3452b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 3453b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; 3454b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 3455b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; 3456b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 3457b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza NUM_BUCKETS - 1, bucketTimeSec, percent); 3458b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 3459b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3460e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName, 3461e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>&& history) { 3462e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 3463e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza auto& stats = mBufferingStats[layerName]; 3464e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& segment : history) { 3465e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (!segment.usedThirdBuffer) { 3466e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.twoBufferTime += segment.totalTime; 3467e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3468e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (segment.occupancyAverage < 1.0f) { 3469e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime += segment.totalTime; 3470e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else if (segment.occupancyAverage < 2.0f) { 3471e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime += segment.totalTime; 3472e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3473e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++stats.numSegments; 3474e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime += segment.totalTime; 3475e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3476e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 3477e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 3478d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) { 3479d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson result.appendFormat("Layer frame timestamps:\n"); 3480d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 3481d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 3482d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const size_t count = currentLayers.size(); 3483d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson for (size_t i=0 ; i<count ; i++) { 3484d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson currentLayers[i]->dumpFrameEvents(result); 3485d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson } 3486d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson} 3487d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 3488e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const { 3489e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("Buffering stats:\n"); 3490e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append(" [Layer name] <Active time> <Two buffer> " 3491e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza "<Double buffered> <Triple buffered>\n"); 3492e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 3493e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza typedef std::tuple<std::string, float, float, float> BufferTuple; 3494e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::map<float, BufferTuple, std::greater<float>> sorted; 3495e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& statsPair : mBufferingStats) { 3496e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const char* name = statsPair.first.c_str(); 3497e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferingStats& stats = statsPair.second; 3498e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (stats.numSegments == 0) { 3499e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza continue; 3500e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3501e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = ns2ms(stats.totalTime) / 1000.0f; 3502e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float twoBufferRatio = static_cast<float>(stats.twoBufferTime) / 3503e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime; 3504e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float doubleBufferRatio = static_cast<float>( 3505e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime) / stats.totalTime; 3506e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float tripleBufferRatio = static_cast<float>( 3507e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime) / stats.totalTime; 3508e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza sorted.insert({activeTime, {name, twoBufferRatio, 3509e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza doubleBufferRatio, tripleBufferRatio}}); 3510e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3511e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& sortedPair : sorted) { 3512e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = sortedPair.first; 3513e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferTuple& values = sortedPair.second; 3514e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.appendFormat(" [%s] %.2f %.3f %.3f %.3f\n", 3515e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<0>(values).c_str(), activeTime, 3516e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<1>(values), std::get<2>(values), 3517e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<3>(values)); 3518e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3519e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("\n"); 3520e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 3521e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 3522f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchtervoid SurfaceFlinger::dumpWideColorInfo(String8& result) const { 3523f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay); 3524f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3525f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter // TODO: print out if wide-color mode is active or not 3526f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3527f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter for (size_t d = 0; d < mDisplays.size(); d++) { 3528f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 3529f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter int32_t hwcId = displayDevice->getHwcDisplayId(); 3530f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 3531f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter continue; 3532f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 3533f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3534f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat("Display %d color modes:\n", hwcId); 3535f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(hwcId); 3536f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter for (auto&& mode : modes) { 3537f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat(" %s (%d)\n", decodeColorMode(mode).c_str(), mode); 3538f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 3539f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3540f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter android_color_mode_t currentMode = displayDevice->getActiveColorMode(); 3541f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat(" Current color mode: %s (%d)\n", 3542f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter decodeColorMode(currentMode).c_str(), currentMode); 3543f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 3544f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.append("\n"); 3545f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter} 3546f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 354774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 354874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 354982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 35503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 35513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 35523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 35533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 35543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 35553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 35563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 35573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 35583e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 355982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 356082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 356182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 356282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 356382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 356482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 3565bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 356682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 35674803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 35684803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 35693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 35703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 35714803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 35723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 35734803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 35744803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 35754803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 35764803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 35774803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 3578f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.append("\nWide-Color information:\n"); 3579f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpWideColorInfo(result); 3580f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 35813e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 3582ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 35833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 3584ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 3585ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 3586ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 35879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 35889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 358941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 359041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 359141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 359224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 3593c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard "present offset %" PRId64 " ns (refresh %" PRId64 " ns)", 35949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, 3595c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod()); 359641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 359741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 3598b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 3599b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3600b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 3601b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3602b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3603e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza dumpBufferingStats(result); 3604e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 36054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 360682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 360782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 36083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 36091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr result.appendFormat("Visible layers (count = %zu)\n", mNumLayers); 36103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 36112047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 36123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 36132047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 3614bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 361582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 36165f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 36175f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 36185f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 36193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 362086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 36213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 36225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 36235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 362474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 36255f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 36265f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 36275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 362882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 362982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 36301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 36313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 363274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 36333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 36341b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 3635888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 36367d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked()); 3637ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 36383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 36393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 36403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 36413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 36423e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 3643ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 3644ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 3645875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 36469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 36474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 36482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 36492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 365074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 365182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 365282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 3653c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 365482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 365582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 3656ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 3657ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 3658ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 365982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 366082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 3661c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 36629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1e9 / activeConfig->getVsyncPeriod(), 36639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiX(), 36649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiY(), 3665ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 366682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 366774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 366882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 366982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 367074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 367182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 367282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 367382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 367482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 367582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 367674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 3677e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3678e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3679e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza /* 3680e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza * HWC layer minidump 3681e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza */ 3682e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t d = 0; d < mDisplays.size(); d++) { 3683e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 3684e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza int32_t hwcId = displayDevice->getHwcDisplayId(); 3685e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 3686e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza continue; 3687e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3688e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3689e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.appendFormat("Display %d HWC layers:\n", hwcId); 3690e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza Layer::miniDumpHeader(result); 36911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 3692e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza layer->miniDump(result, hwcId); 36931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 3694e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3695e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 369682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 369782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 369882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 369982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 37003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 370174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 37023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 37039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza bool hwcDisabled = mDebugDisableHWC || mDebugRegion; 37049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza result.appendFormat(" h/w composer %s\n", 37059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcDisabled ? "disabled" : "enabled"); 370674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 370782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 370882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 370982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 371082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 371182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 371282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 3713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 371513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 371648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 3717db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 371848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 371948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 372048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 372148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 372248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 372348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 372448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 372548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 372648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 372748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 372848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 372948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 37307d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ(); 3731cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 3732cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 373363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 373463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 373563f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 373663f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 373763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 373863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 373963f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 374063f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 374163f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 374224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 374363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 374463f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 374563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 374663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 374763f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 374863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 374963f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 375063f165fd6b86d04be94d4023e845e98560504a96Keun young Park 37516e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { 3752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 3753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 3754041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 3755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 3756d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 3757d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 37582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 3759c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza case GET_HDR_CAPABILITIES: 3760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 3761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 3762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 3763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 3764a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 37653bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 376699b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 37676e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3768375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 3769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 37701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 37711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 37721db73f66624e7d151710483dd58e03eed672f064Robert Carr /* 37731db73f66624e7d151710483dd58e03eed672f064Robert Carr * Calling setTransactionState is safe, because you need to have been 37741db73f66624e7d151710483dd58e03eed672f064Robert Carr * granted a reference to Client* and Handle* to do anything with it. 37751db73f66624e7d151710483dd58e03eed672f064Robert Carr * 37761db73f66624e7d151710483dd58e03eed672f064Robert Carr * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h 37771db73f66624e7d151710483dd58e03eed672f064Robert Carr */ 37781db73f66624e7d151710483dd58e03eed672f064Robert Carr case SET_TRANSACTION_STATE: 37791db73f66624e7d151710483dd58e03eed672f064Robert Carr case CREATE_SCOPED_CONNECTION: 37801db73f66624e7d151710483dd58e03eed672f064Robert Carr { 37811db73f66624e7d151710483dd58e03eed672f064Robert Carr return OK; 37821db73f66624e7d151710483dd58e03eed672f064Robert Carr } 37831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 37841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 37851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 37861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 37871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 37881b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 378999b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 379099b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 37916e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid); 37921b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 37931b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 37941b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 3795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 37976e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return OK; 37986e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard} 37996e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard 38006e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact( 38016e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 38026e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{ 38036e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard status_t credentialCheck = CheckTransactCodeCredentials(code); 38046e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard if (credentialCheck != OK) { 38056e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return credentialCheck; 38066e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard } 38071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 3809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 3810b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 381199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 3812375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3813375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 3814375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 3815e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 3816375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 3818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 3820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 382101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 382235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 3823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 3825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 3826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 382753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 382853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 383153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3832cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3833cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 3834cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 3835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 3836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 3837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 3838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 3839cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 38414d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 38424d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 38434d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 38444d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 384553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 384653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 384753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 384853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 384953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 385053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 3851a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 3852a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 3853a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 3854a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 3855a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 3856a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 3857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 385801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 3859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 3860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 3861b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 386212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 3863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 38658722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 38664297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 3867ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 3868ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3869ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 3870ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 3871ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 3872ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 38739f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 1: 38749f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Protanomaly); 38759f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 38769f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 2: 38779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); 38789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 38799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 3: 38809f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Tritanomaly); 38819f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 38829f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza default: 38839f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::None); 38849f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 3885ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3886ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 38879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Correction); 3888ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 38899f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Simulation); 3890ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3891ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 3892ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 38939c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 38949c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 38959c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 38969c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 38979c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 38989c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 38999c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 39009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 39019c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 3902794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 39039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza for (size_t j = 0; j < 4; j++) { 39049f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mColorMatrix[i][j] = data.readFloat(); 39059f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 39069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 39079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 39089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 39099c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 39109c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 39119c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 39129c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 3913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3914f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 3915f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 3916f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 3917645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 3918645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 3919f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 3920f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 3921ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 3922ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 3923ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 3924ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 3925ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 3926db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 3927db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3928db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3929db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3930db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3931db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 3932db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3933db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3934db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3935db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3936468051e20be19130572231266db306396a56402bIrvel case 1020: { // Layer updates interceptor 3937468051e20be19130572231266db306396a56402bIrvel n = data.readInt32(); 3938468051e20be19130572231266db306396a56402bIrvel if (n) { 3939468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor enabled"); 3940ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays); 3941468051e20be19130572231266db306396a56402bIrvel } 3942468051e20be19130572231266db306396a56402bIrvel else{ 3943468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor disabled"); 3944468051e20be19130572231266db306396a56402bIrvel mInterceptor.disable(); 3945468051e20be19130572231266db306396a56402bIrvel } 3946468051e20be19130572231266db306396a56402bIrvel return NO_ERROR; 3947468051e20be19130572231266db306396a56402bIrvel } 39488cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza case 1021: { // Disable HWC virtual displays 39498cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza n = data.readInt32(); 39508cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !n; 39518cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza return NO_ERROR; 39528cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 3953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 3956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 395853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 395987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 396099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 396153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 396253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 396359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 39642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 39652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 396659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 39672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 39682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 39692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 3970b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 3971b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 3972b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 3973b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 39742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 39752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 3976b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 3977b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 3978b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 3979b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3980b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 3981b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 3982b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 3983b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 3984b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3985b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 3986b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 3987b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 3988b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 3989b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 39902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 39912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 39922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 39932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 39942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 3995b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 39962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 39972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 39982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 39992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 40012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 40022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 40032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 40042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 4006b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 4007b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 4008b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 40092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 40102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 4011c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 40122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 40132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 40142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 40152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 4016b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 4017b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 4018b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 4019b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 40202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 40212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 40222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 4023b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 4024b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 4025b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 40262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 40272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 40282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 4029c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 40302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 40312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 4033b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 40342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 40352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 40362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 4037b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 4038b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 4039b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 4040b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 4041097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 40422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 4043b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 40442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 40452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 40462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 40472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 4049c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 4050b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 4051b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 405253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos result(NO_ERROR), 4053b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 405453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos exitRequested(false), 405553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos code(0), 405653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos data(NULL), 405753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos reply(NULL) 4058b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 4059b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 4060b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 40612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 40622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 40632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 40642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 40652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 40662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 40672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 4068b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 40692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 4070aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 40712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 4072b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 4073b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 4074b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 40752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 40762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 40772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 40782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 40802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 40812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 4082c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 4083ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 4084c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 40852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 40862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 40872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 40882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 40892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 40902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 40912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 40925ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 40935ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 40945ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 4095b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder(); 40965ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 4097c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 4098c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 4099c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 4100c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 4101c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 4102c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 4103c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 4104c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 4105c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 4106c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 4107c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 4108c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 4109c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 4110c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 4111c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 4112c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 4113c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 4114c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 4115c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 4116c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 4117c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 41182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 41192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 41202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 41212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 4122c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 41232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 41242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 4125c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 4126c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 41272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 4128b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot; 41292a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 41302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 41312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 41322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 4133c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 4134ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 4135b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, 4136b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos Transform::orientation_flags rotation, 4137b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 41382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 4139c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 41402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 4141c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 4142b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos rotation(rotation), result(PERMISSION_DENIED), 4143b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos isLocalScreenshot(isLocalScreenshot) 41442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 41452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 41462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 41472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 41482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 41492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 41502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 41517d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> hw(flinger->getDisplayDeviceLocked(display)); 4152c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 4153c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 4154b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotation, isLocalScreenshot); 4155097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 41562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 41572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 41582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 41592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 41602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 41612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 41622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 41632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 41642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 41652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 41662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 41672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 41682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 4169c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 4170b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotationFlags, isLocalScreenshot); 41712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 41722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 41732a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 41742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 41752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 41762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 4177118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 4178118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 4179180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4180180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 4181180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 4182c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 4183ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 4184c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 4185180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 4186180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 41873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 4188180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4189180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 419089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 419189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 419289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 41930e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 4194180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4195c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 4196c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 4197c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 4198c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 4199c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 4200c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4201c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 4202c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 4203c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 4204c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 4205c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4206be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 4207be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 4208c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4209c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 4210c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 4211c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4212be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 4213be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 4214c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4215c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 4216180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 42173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 4218180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4219180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 4220c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 4221c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 42223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 4223180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4224180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 42253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 4226180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 42271f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // We loop through the first level of layers without traversing, 42281f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // as we need to interpret min/max layer Z in the top level Z space. 42291f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr for (const auto& layer : mDrawingState.layersSortedByZ) { 42301f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (layer->getLayerStack() != hw->getLayerStack()) { 42311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr continue; 42321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 42331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 42341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (state.z < minLayerZ || state.z > maxLayerZ) { 42351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr continue; 4236180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 4237412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { 42381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (!layer->isVisible()) { 42391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return; 42401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 42411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (filtering) layer->setFiltering(true); 42421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->draw(hw, useIdentityTransform); 42431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (filtering) layer->setFiltering(false); 42441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 42451f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 4246180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4247931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 4248180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 4249180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4250180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 42512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 42522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 42532a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 4254c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 4255ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 4256b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, Transform::orientation_flags rotation, 4257b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 425874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 4259fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 4260fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 4261180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 42623502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_w = hw->getWidth(); 42633502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_h = hw->getHeight(); 42643502416204d9dbd905012ee586d8bd145323809fDan Stoza 42653502416204d9dbd905012ee586d8bd145323809fDan Stoza if (rotation & Transform::ROT_90) { 42663502416204d9dbd905012ee586d8bd145323809fDan Stoza std::swap(hw_w, hw_h); 42673502416204d9dbd905012ee586d8bd145323809fDan Stoza } 4268180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4269180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 4270180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 4271180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 4272180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 4273180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 4274180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4275180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 4276180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 4277180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4278b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool secureLayerIsVisible = false; 42791f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr for (const auto& layer : mDrawingState.layersSortedByZ) { 4280b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const Layer::State& state(layer->getDrawingState()); 42811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if ((layer->getLayerStack() != hw->getLayerStack()) || 42821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr (state.z < minLayerZ || state.z > maxLayerZ)) { 42831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr continue; 4284b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 4285412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer *layer) { 42861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && 42871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->isSecure()); 42881f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 42891f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 4290b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 4291b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (!isLocalScreenshot && secureLayerIsVisible) { 4292b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos ALOGW("FB is protected: PERMISSION_DENIED"); 4293b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos return PERMISSION_DENIED; 4294b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 4295b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 42960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 42970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 429883cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 4299605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 4300605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Put the screenshot Surface into async mode so that 4301605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Layer::headFenceHasSignaled will always return true and we'll latch the 4302605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // first buffer regardless of whether or not its acquire fence has 4303605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // signaled. This is needed to avoid a race condition in the rotation 4304605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // animation. See b/30209608 4305605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos sur->setAsyncMode(true); 4306605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 43070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 430874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 43095a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 43105a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine if (result == NO_ERROR) { 43113ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 43123ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 43132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 43140aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 43150aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 43164ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 43170aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 43180aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 43192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 43200aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 43210aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 43220aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 43230aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 43240aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 43250aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 43260aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 4327866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 43280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 43290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 43300aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 43310aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 43320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 43333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 43343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 43353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 43363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 43370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 43380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 43390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 43400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 4341c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 4342c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 4343c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 4344d555684cb36dfb959694db76962e570184f98838Mathias Agopian 4345866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 4346866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 4347866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 4348866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 4349866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 4350866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 43519707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 43529707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 4353866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 4354866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 4355866399093f9f60e7305f291e688abb456bace710Riley Andrews } 43562d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 4357866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 4358866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 4359866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 4360866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 4361866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 4362866399093f9f60e7305f291e688abb456bace710Riley Andrews } 43632d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 4364866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 4365866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 4366866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 4367866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 4368866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 4369866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 4370866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 4371866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 4372866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 4373866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 4374866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 4375866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 4376866399093f9f60e7305f291e688abb456bace710Riley Andrews } 4377866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 43782d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 4379866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 43802d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 43812d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 4382d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 4383d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 4384d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 4385d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 4386d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 4387d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 4388d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 4389d555684cb36dfb959694db76962e570184f98838Mathias Agopian 43900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 43910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 43920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 4393f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu window->cancelBuffer(window, buffer, syncFd); 4394f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu buffer = NULL; 43950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 43960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 43970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 43980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 43990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 440074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 4401f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu if (buffer) { 4402f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu // queueBuffer takes ownership of syncFd 4403f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu result = window->queueBuffer(window, buffer, syncFd); 4404f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu } 440574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 44060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 44070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 440874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 44090aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 441074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 441174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 441274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 441374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 441474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 4415d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 4416ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) { 4417fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 4418d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 4419d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 4420d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 4421fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 4422fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 4423fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 4424fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 4425fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 4426fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 44271f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 44282047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr size_t i = 0; 44291f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr for (const auto& layer : mDrawingState.layersSortedByZ) { 4430fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 44311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ && 44321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr state.z <= maxLayerZ) { 4433412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { 44341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", 44351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->isVisible() ? '+' : '-', 44361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr i, layer->getName().string(), layer->getLayerStack(), state.z, 4437fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 44381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr i++; 44391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 44401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 44411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 4442fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 4443ce796e78a57018f186b062199c75d94545318acaPablo Ceballos} 4444ce796e78a57018f186b062199c75d94545318acaPablo Ceballos 44451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 44461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 4447412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const { 4448412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layersSortedByZ.traverseInZOrder(stateSet, visitor); 4449921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 4450921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 4451412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const { 4452412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layersSortedByZ.traverseInReverseZOrder(stateSet, visitor); 4453921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 4454921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 4455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 44563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 44573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 44583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 44593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 44603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 44613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 44623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 44633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 44643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 4465