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