SurfaceFlinger.cpp revision 598f6d5429b290f33107ef678328914b99c8312e
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> 2463f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 2586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h> 26b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h> 27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 357303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3699b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 38c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 3967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h> 40c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 41921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 45e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 46392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 51d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 52cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 560a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h> 571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 59921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 60ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 660f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 67faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 68d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 69d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 75a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 81ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 82875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 91ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 92ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12699b49840d309727678b77403d6cc9f920111623fMathias Agopian 12799b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12899b49840d309727678b77403d6cc9f920111623fMathias Agopian 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1304f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 136875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mBuiltinDisplays(), 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid(false), 1414b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1438afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 145a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 150ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 151ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 1524a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mPrimaryDispSync("PrimaryDispSync"), 153faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 154948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasColorMatrix(false), 156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff(false), 157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets(), 158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime(0), 159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime(0) 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 161a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 166b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 16750210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 168b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1738afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 17663f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 17763f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 17863f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1798afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 180c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 181c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 182c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza 183c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza property_get("debug.sf.disable_backpressure", value, "0"); 184c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza mPropagateBackpressure = !atoi(value); 185c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation"); 1863cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza 1873cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza property_get("debug.sf.disable_hwc_vds", value, "0"); 1883cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza mUseHwcVirtualDisplays = !atoi(value); 1893cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays"); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 199a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 200a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 201a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 204c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 20599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 20699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 20799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 20813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 20913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 21099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 212a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 21399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 21499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2157e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 21896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 21996f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 22096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 22196f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 227dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 24653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure); 2478dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 2739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("createBuiltinDisplayLocked(%d)", type); 274692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 275692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 276692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 277692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 27853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(type, true); 279692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 280692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 281692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2839e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 288e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2909a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2919a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2929a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2939a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 300a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 3013330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 3021f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3031f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 3041f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 3051f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 3061f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 3081f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 3091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 311a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 312a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 313a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 3140a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato 3150a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato const int LOGTAG_SF_STOP_BOOTANIM = 60110; 3160a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, 3170a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 324921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 327921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 328921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 330921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 332921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3385167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3394a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* name) : 3404a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mName(name), 3410a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3420a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3434a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncOnLabel(String8::format("VsyncOn-%s", name)), 3444a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncEventLabel(String8::format("VSYNC-%s", name)), 345db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mDispSync(dispSync), 346db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallbackMutex(), 347db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallback(), 348db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mVsyncMutex(), 349db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset(phaseOffset), 350db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled(false) {} 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 355db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3574a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray status_t err = mDispSync->addEventListener(mName, mPhaseOffset, 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3635167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3715167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 373db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled = enable; 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 377db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 379faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 380faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 381db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza virtual void setPhaseOffset(nsecs_t phaseOffset) { 382db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Normalize phaseOffset to [0, period) 385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza auto period = mDispSync->getPeriod(); 386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset %= period; 387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (phaseOffset < 0) { 388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're here, then phaseOffset is in (-period, 0). After this 389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // operation, it will be in (0, period) 390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset += period; 391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset = phaseOffset; 393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're not enabled, we don't need to mess with the listeners 395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (!mEnabled) { 396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return; 397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Remove the listener with the old offset 400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza status_t err = mDispSync->removeEventListener( 401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error unregistering vsync callback: %s (%d)", 404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Add a listener with the new offset 4084a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray err = mDispSync->addEventListener(mName, mPhaseOffset, 409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error registering vsync callback: %s (%d)", 412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 416faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 422a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 4240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 4255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 4260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 431faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4344a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* const mName; 4354a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 436faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4380a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 4395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 4405167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 4410a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 442faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mCallbackMutex; // Protects the following 445faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 446db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 447db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mVsyncMutex; // Protects the following 448db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza nsecs_t mPhaseOffset; 449db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza bool mEnabled; 450faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 451faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 453a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 454a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 455a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza { // Autolock scope 4579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 4589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 4599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize EGL for the default display 4609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 4619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza eglInitialize(mEGLDisplay, NULL, NULL); 462692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 4639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // start the EventThread 4649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, true, "app"); 4664a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mEventThread = new EventThread(vsyncSrc, *this); 4679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sfVsyncPhaseOffsetNs, true, "sf"); 4694a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mSFEventThread = new EventThread(sfVsyncSrc, *this); 4709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEventQueue.setEventThread(mSFEventThread); 471a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 472acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray // set SFEventThread to SCHED_FIFO to minimize jitter 47341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray struct sched_param param = {0}; 47435520634e298f53bd8433825640d6999760f25b3Tim Murray param.sched_priority = 2; 47541a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { 47641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray ALOGE("Couldn't set SCHED_FIFO for SFEventThread"); 47741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray } 47841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray 4799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Get a RenderEngine for the given display / config (can't fail) 4809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine = RenderEngine::create(mEGLDisplay, 4819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza HAL_PIXEL_FORMAT_RGBA_8888); 4829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 483f9481058101c4e2b38c74048feac383664691d03Saurabh Shah 4849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Drop the state lock while we initialize the hardware composer. We drop 4859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // the lock because on creation, it will call back into SurfaceFlinger to 4869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize the primary display. 4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc = new HWComposer(this); 4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this)); 489b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 493875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 495da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 496da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 497da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // make the GLContext current so that we can create textures when creating 4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Layers (which may happens before we render something) 500a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 501a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 502d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 503d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 504d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 50592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 50692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 5078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 50813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 50913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 51013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 5114e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza mRenderEngine->primeCache(); 5124e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza 513a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 514a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Done initializing"); 5173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 5183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 519a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 520a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 521a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 522a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 523a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 524a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 525875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 526875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 527a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 528a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 529875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 530875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 531a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 532a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 534d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 535582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 5362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 537134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 538097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 5396710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 540134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 541134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 54423e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa if ((configs == NULL) || (display.get() == NULL)) { 5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5487aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 5497aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 5507aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 551692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5529e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 553692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5571604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5581604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 561c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5628b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5638b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5648b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5658b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5668b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5678b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5688b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5698b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5708b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5718b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5728b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5738b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5748b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5758b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5791604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 5817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (const auto& hwConfig : getHwComposer().getConfigs(type)) { 5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 5847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float xdpi = hwConfig->getDpiX(); 5869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float ydpi = hwConfig->getDpiY(); 5877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5887f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 5897f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 5907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 5917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 5927f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 6067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 6097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 6107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 6117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 6121604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.w = hwConfig->getWidth(); 6159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.h = hwConfig->getHeight(); 6167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 6177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 6189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.fps = 1e9 / hwConfig->getVsyncPeriod(); 61991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 6209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 62191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 62291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 62391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 62491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 62591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 62691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 62791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 62891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 62991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 63091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 63191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 63291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.presentationDeadline = hwConfig->getVsyncPeriod() - 6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 63928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright configs->push_back(info); 6408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 644dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 64589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 64667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 64767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 64867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 64967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 65067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 65167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 65267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 65367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 65467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 65567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 65667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 65767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 6586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 65924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza sp<DisplayDevice> device(getDisplayDevice(display)); 66024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 66124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 66224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 66324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 6647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 665dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 6706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6766c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 6796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6826c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 6836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 6846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 6856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 6876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 6886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 6896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 6906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 6916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 6926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 6936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 6946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 6956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 6967306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 6977306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 698784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 6999ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 7007306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 70128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 7027306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 7036c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 7046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 7056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 7067306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 7146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 7166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 7176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 718888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 719c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 72028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display, 72128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t>* outColorModes) { 72228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if ((outColorModes == nullptr) || (display.get() == nullptr)) { 72328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return BAD_VALUE; 72428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 72528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 72628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (!display.get()) { 72728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NAME_NOT_FOUND; 72828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 72928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 73028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = NAME_NOT_FOUND; 73128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 73228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (display == mBuiltinDisplays[i]) { 73328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright type = i; 73428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright break; 73528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 73628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 73728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 73828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type < 0) { 73928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return type; 74028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 74128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 74228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type); 74328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright outColorModes->clear(); 74428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); 74528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 74628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 74728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 74828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 74928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) { 75028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> device(getDisplayDevice(display)); 75128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (device != nullptr) { 75228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return device->getActiveColorMode(); 75328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 75428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return static_cast<android_color_mode_t>(BAD_VALUE); 75528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 75628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 75728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw, 75828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) { 75928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 76028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright this); 76128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = hw->getDisplayType(); 76228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t currentMode = hw->getActiveColorMode(); 76328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 76428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mode == currentMode) { 76528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode); 76628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 76728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 76828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 76928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 77028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Trying to set config for virtual display"); 77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright hw->setActiveColorMode(mode); 77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright getHwComposer().setActiveColorMode(type, mode); 77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display, 78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t colorMode) { 78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright class MessageSetActiveColorMode: public MessageBase { 78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright SurfaceFlinger& mFlinger; 78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<IBinder> mDisplay; 78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mMode; 78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright public: 78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp, 78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) : 78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger(flinger), mDisplay(disp) { mMode = mode; } 78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright virtual bool handler() { 79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t> modes; 79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.getDisplayColorModes(mDisplay, &modes); 79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes); 79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mMode < 0 || !exists) { 79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode, 79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mDisplay.get()); 79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (hw == nullptr) { 80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set active color mode = %d for null display %p", 80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode, mDisplay.get()); 80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Attempt to set active color mode= %d for virtual display", 80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode); 80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else { 80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.setActiveColorModeInternal(hw, mMode); 80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright }; 81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode); 81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright postMessageSync(msg); 81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 815c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 816d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 817d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 818d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 819d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 820d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 821d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 822d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 823d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 824d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 825d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 826d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 827d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 828c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, 829c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza HdrCapabilities* outCapabilities) const { 830c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza Mutex::Autolock _l(mStateLock); 831c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 832c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza sp<const DisplayDevice> displayDevice(getDisplayDevice(display)); 833c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (displayDevice == nullptr) { 834c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get()); 835c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 836c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 837c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 838c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::unique_ptr<HdrCapabilities> capabilities = 839c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); 840c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (capabilities) { 841c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::swap(*outCapabilities, *capabilities); 842c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } else { 843c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 844c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 845c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 846c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return NO_ERROR; 847c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza} 848c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 849d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 850d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 851d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 8528aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 853bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 854bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 85699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 85799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 85899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 85999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 86099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 86199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 86299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 86399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 86499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 86599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 86699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 86799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 86899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 86999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 87099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 87199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 87299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 87399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 874c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 87599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 87699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 87799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 87899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 879c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 88099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 88199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 88299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 88399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 88499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 88599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8874f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 8884f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 8894f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 8904f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 89199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 893faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 894faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 895948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 896faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 897d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 898d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 899faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 90043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 901faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 902faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 903948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 904faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 905faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 906948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 907948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 908948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 9090a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // Hardware vsync is not currently available, so abort the resync 9100a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // attempt for now 911948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 912948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 913948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 9149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 9159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 916faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 917faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 918faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 919faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 920faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 921faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 922d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 923d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 924faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 925faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 926faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 927faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 928948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 929faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 931d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 932d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 933faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 934faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 935faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 936948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 937948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 938948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 939faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 940faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9414a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() { 9424a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray static constexpr nsecs_t kIgnoreDelay = ms2ns(500); 9434a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray if (systemTime() - mLastSwapTime > kIgnoreDelay) { 9440a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza resyncToHardwareVsync(false); 9454a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray } 9464a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray} 9474a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 9489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) { 949d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 950faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 951d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 952d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 953d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 954d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 955faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 956148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 957d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 958d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 959d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 960d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 961d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 962d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 963148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 964148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 9659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) { 9669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false"); 9679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (disp == DisplayDevice::DISPLAY_PRIMARY) { 9689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock lock(mStateLock); 9699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 9709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // All non-virtual displays are currently considered secure. 9719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool isSecure = true; 9729e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 9739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t type = DisplayDevice::DISPLAY_PRIMARY; 9749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY); 9759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza wp<IBinder> token = mBuiltinDisplays[type]; 9769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 9779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferProducer> producer; 9789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferConsumer> consumer; 9799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 9809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new GraphicBufferAlloc()); 9819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 9829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, 9839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, consumer); 9849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<DisplayDevice> hw = new DisplayDevice(this, 9859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs, 9869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer, mRenderEngine->getEGLConfig()); 9879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mDisplays.add(token, hw); 9889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 9899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto type = DisplayDevice::DISPLAY_EXTERNAL; 9909e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 991692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 9929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(type); 9939e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 994692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 995692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 9969e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 9979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 9989e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 9999e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 10003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 10018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10028630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) { 1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 10059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza getHwComposer().setVsyncEnabled(disp, 10069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); 10078630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10088630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 10101c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 101199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 10126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 10135018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza bool frameMissed = !mHadClientComposition && 10145018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence != Fence::NO_FENCE && 10155018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence->getSignalTime() == INT64_MAX; 10165018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); 1017c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza if (mPropagateBackpressure && frameMissed) { 10185018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza signalLayerUpdate(); 10195018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza break; 10205018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza } 10215018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza 10226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 10236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 10245878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 10256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 10265878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 10275878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 10285878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 10296b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 10306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 10316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 10326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 10336b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 10346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 10356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 10366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 10374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10406b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 1041e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 10424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 104387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 10446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 10454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 10466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 10474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10496b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 1050cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 10516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 10524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 10533a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 10544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 1055cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 105614cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 105740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 105805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 105905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza preComposition(); 106005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza rebuildLayerStacks(); 106105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza setUpHWComposer(); 106205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doDebugFlashRegions(); 106305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doComposition(); 106405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza postComposition(refreshStartTime); 106505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 106605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY); 1067bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza 1068bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = false; 1069bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1070bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1071bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = mHadClientComposition || 1072bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); 1073bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza } 107414cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Release any buffers which were replaced this frame 10769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->releasePendingBuffer(); 10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.clear(); 1080cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1081cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1082cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 1083cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 1084cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 1085cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 1086cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 1087cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1088cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 1089cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1090cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 10912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1092cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1093cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1094cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 1095cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 1096cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 1097cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1098cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 1099cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 11003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 11013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 11023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1103da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1104cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1105cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1106cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1107cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 1109cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1110cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 1111cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 1112cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1113bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 11149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 11157bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 11167bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 11177bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 11187bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 11197bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 11207bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 11219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 11229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 1123bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1125cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1126cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 1127cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 11289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 11299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("preComposition"); 11309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1131cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 11321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 11331eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1134cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 11351eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 1136cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 1137cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1138cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1139cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 1140cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1142cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1143a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 114440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime) 1145cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 11469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 11479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postComposition"); 11489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 11491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 11501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1151cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 1152e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza bool frameLatched = layers[i]->onPostComposition(); 1153e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (frameLatched) { 1154e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordBufferingStats(layers[i]->getName().string(), 1155e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza layers[i]->getOccupancyHistory(false)); 1156e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 1157cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 11584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 11599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> presentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY); 1160faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1161faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 1162faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 1163faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1164faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1165948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1166faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1167faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1168faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1169b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 11705167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 11712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1172faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1173faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1174faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1175faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 117640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos mFenceTracker.addFrame(refreshStartTime, presentFence, 117740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence()); 117840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 11794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 11804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 11814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 1182a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 11834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 11844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 11854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 11864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 11879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nsecs_t presentTime = 11889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 11894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 11904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 11914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 11924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1193b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1194b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1195b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1196b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1197b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1198b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1199b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1200b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1201b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1202b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t period = mPrimaryDispSync.getPeriod(); 1203b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t elapsedTime = currentTime - mLastSwapTime; 1204b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza size_t numPeriods = static_cast<size_t>(elapsedTime / period); 1205b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (numPeriods < NUM_BUCKETS - 1) { 1206b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[numPeriods] += elapsedTime; 1207b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1208b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; 1209b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1210b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime += elapsedTime; 1211b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1212b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime = currentTime; 1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 12169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("rebuildLayerStacks"); 12189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1219cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 122052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1221cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 122287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 122387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 1224ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 12251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 122692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1227ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 1228ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 12299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Vector<sp<Layer>> layersSortedByZ; 12309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<DisplayDevice>& displayDevice(mDisplays[dpy]); 12319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& tr(displayDevice->getTransform()); 12329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect bounds(displayDevice->getBounds()); 12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->isDisplayOn()) { 12341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 12359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getLayerStack(), dirtyRegion, 12369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza opaqueRegion); 12377e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 12381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1239ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 12401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 12411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 12429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.layerStack == displayDevice->getLayerStack()) { 1243a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 1244a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 1245a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 1246a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 1247ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 12489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 12499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Clear out the HWC layer if this layer was 12509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // previously visible, but no longer is 12519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(displayDevice->getHwcDisplayId(), 12529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nullptr); 1253ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 125487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 125587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 12563b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 12579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); 12589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.set(bounds); 12599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.subtractSelf( 12609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza tr.transform(opaqueRegion)); 12619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->dirtyRegion.orSelf(dirtyRegion); 12623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 12633b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1264cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 12653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1266cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 12679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("setUpHWComposer"); 12699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1270028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1271b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1272b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1273b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1274b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1275b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1276b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1277b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1278b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1279b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1280b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1281b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1282b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1283b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1284b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1285b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1286b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1287b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1288b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1289b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1290b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1291b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 12927143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1293b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1294b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1295b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1296b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1297028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1298028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 12999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // build the h/w work list 13009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (CC_UNLIKELY(mGeometryInvalid)) { 13019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = false; 13029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 13039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<const DisplayDevice> displayDevice(mDisplays[dpy]); 13049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 13059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 13069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Vector<sp<Layer>>& currentLayers( 13079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getVisibleLayersSortedByZ()); 13089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool foundLayerWithoutHwc = false; 13099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : currentLayers) { 13109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!layer->hasHwcLayer(hwcId)) { 13119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = mHwc->createLayer(hwcId); 13129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcLayer) { 13139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(hwcId, std::move(hwcLayer)); 13149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 13159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 13169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza foundLayerWithoutHwc = true; 13179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 1318a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1319a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1320a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 13219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setGeometry(displayDevice); 13229f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (mDebugDisableHWC || mDebugRegion) { 13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 132403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 132503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 132603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 132703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 13289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 132903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 13309f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 13319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 13329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Set the per-frame data 13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId < 0) { 13389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 13409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (colorMatrix != mPreviousColorMatrix) { 13419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza status_t result = mHwc->setColorTransform(hwcId, colorMatrix); 13429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " 13439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza "display %zd: %d", displayId, result); 13449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 13459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 13469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setPerFrameData(displayDevice); 134738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 134852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 13499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 13509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mPreviousColorMatrix = colorMatrix; 13519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 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)); 13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1362cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 136352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1364cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1365cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 13669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposition"); 13679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 136852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 136992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 13704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 13712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1372cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1373cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 137402b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 137502b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 137602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 137702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1378cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1379cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1380cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 138187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 13824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 138352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1388841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 13899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postFramebuffer"); 1390b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1391a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1392a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1393c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 13949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 13959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 13967bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 13977bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 13987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 13999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 14009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 14019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->commit(hwcId); 14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14032dc3be88bd85791556ab0e6df6a080989886749eDan Stoza displayDevice->onSwapBuffersCompleted(); 14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayId == 0) { 14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Make the default display current because the VirtualDisplayDevice 14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // code cannot deal with dequeueBuffer() being called outside of the 14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // composition loop; however the code below can call glFlush() which 14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // is allowed to (and does in some case) call dequeueBuffer(). 14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->makeCurrent(mEGLDisplay, mEGLContext); 14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> releaseFence = Fence::NO_FENCE; 14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) { 14149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = displayDevice->getClientTargetAcquireFence(); 14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = layer->getHwcLayer(hwcId); 14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer); 141852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->onLayerDisplayed(releaseFence); 14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 14229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->clearReleaseFences(hwcId); 1423ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1424e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1425e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1426a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1427a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 14286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 14296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 14306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 14316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 14326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 143587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1437841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1438841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 14397cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 14407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 14417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 14427cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 14437cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 14447cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1445ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1446ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1447ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1448ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1449ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1450ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1451ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1452ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1453ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1454ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 145687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1457ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1458ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1459ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1460ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1461ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 14623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 14653d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 14663d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // Notify all layers of available frames 14707dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza for (size_t i = 0; i < count; ++i) { 14717dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza currentLayers[i]->notifyAvailableFrames(); 14727dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 14737dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14793559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 148113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 14923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 149692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 149792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 149892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 150192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 150392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 150493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 150592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 150692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 150792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 150892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 150992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 151092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 151392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 15143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 151527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 151627ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 151727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 151802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1519875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 152002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 152102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 152202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 15239e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 15247adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 152502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 152692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 152792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 152892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 152992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 153092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 15323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1533097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1534097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 15351474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 153793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 153893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 153993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 154002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 154102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 154202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 154393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 154493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 154593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 154693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 154793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 154892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 154993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1550db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 155193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 155293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 155393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 155493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 155500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 155600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 155700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 155800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 155900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 15604fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 156193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 156247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 156347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 156447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 156592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 156692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 156792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 156892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 156992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 157092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 157192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1572e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1573e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1574cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 157599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1576db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1577b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1578b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 157970982a5f95f68295244e5f6cc037c193713a5259Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 158070982a5f95f68295244e5f6cc037c193713a5259Dan Stoza new GraphicBufferAlloc()); 1581db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 15829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t hwcId = -1; 158399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 158402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 158502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 158602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 158799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1588db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 15893cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza if (mUseHwcVirtualDisplays) { 15903cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza int width = 0; 15913cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza int status = state.surface->query( 15923cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza NATIVE_WINDOW_WIDTH, &width); 15933cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza ALOGE_IF(status != NO_ERROR, 15943cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza "Unable to query width (%d)", status); 15953cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza int height = 0; 15963cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza status = state.surface->query( 15973cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza NATIVE_WINDOW_HEIGHT, &height); 15983cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza ALOGE_IF(status != NO_ERROR, 15993cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza "Unable to query height (%d)", status); 16003cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza int intFormat = 0; 16013cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza status = state.surface->query( 16023cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza NATIVE_WINDOW_FORMAT, &intFormat); 16033cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza ALOGE_IF(status != NO_ERROR, 16043cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza "Unable to query format (%d)", status); 16053cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza auto format = static_cast<android_pixel_format_t>( 16063cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza intFormat); 16073cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza 16083cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza mHwc->allocateVirtualDisplay(width, height, &format, 16093cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza &hwcId); 16103cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza } 16119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 16125cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza // TODO: Plumb requested format back up to consumer 16135cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza 16149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VirtualDisplaySurface> vds = 16159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new VirtualDisplaySurface(*mHwc, 16169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId, state.surface, bqProducer, 16179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer, state.displayName); 1618db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1619db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 162047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 162199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 162299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1623cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1624cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1625cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1626cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 16279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (state.type == DisplayDevice::DISPLAY_EXTERNAL) { 16289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId = DisplayDevice::DISPLAY_EXTERNAL; 16299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface = new FramebufferSurface(*mHwc, 16309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_EXTERNAL, 16319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer); 16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer = bqProducer; 16339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 16349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("Attempted to add non-external non-virtual" 16359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " display"); 16369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1637cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1638cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1639cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 164099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1641cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 16429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza state.type, hwcId, state.isSecure, display, 16439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface, producer, 164405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1645cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1646cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 16474fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 16488dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1649cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 16509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!state.isVirtualDisplay()) { 16517adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 16521c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 165393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 165492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 165592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 16573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 16608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 16618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 16628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 16638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 16648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 16658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 16668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 16678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 16688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 16698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 16708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 16718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 16728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 16738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 16748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 16758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 16768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 16778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 16788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 16798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 16808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 16818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 16828430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 16838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 16848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 168513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 16861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 16878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 16888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 16898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 16908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 16918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 16928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 16938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 16948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 16958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 16968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 16978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 16988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 169991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 17008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 17018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 170591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 170691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 170791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 170891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 170991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 171091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 171191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 171291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 17138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 171491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 17158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 17188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 17193559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 17203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 17213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 17241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 17253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 17263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 17273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 17283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 17293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 17303559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 17313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 17323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 17333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 17341eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 17353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 17361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 17373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 17383559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 17393559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 17403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 17413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 17421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 17433dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Region visibleReg = s.active.transform.transform( 17441501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 17451501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 17460aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 175103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 175203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 175303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 175403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 175503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 175603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 17579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 17589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 17599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getHwcDisplayId() < 0) { 176003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 176103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 17629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 17639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 17649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->updateCursorPosition(displayDevice); 176503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 176603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 17674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 17684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 17694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 17704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 1771598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (!mLayersPendingRemoval.isEmpty()) { 17724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 17734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 1774e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordBufferingStats(mLayersPendingRemoval[i]->getName().string(), 1775e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mLayersPendingRemoval[i]->getOccupancyHistory(true)); 17764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 17774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 17784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 17794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 17804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 17814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 17824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 17834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 17844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 17854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 17862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 17872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 17884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 179287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 179387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1795841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 17969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("computeVisibleRegions"); 1797841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 180287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 180613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 18091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 181101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 181287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 181387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 181487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1815ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1816ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1817ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1819ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1820ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1821ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1822ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1823ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1824ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1825ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1827ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1828ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1829ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1830ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1831ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1832edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1833ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1834a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1835a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1836a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1837a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1838a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1839a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1840a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1841a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1842a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1843a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1844ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1845ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1846da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 18474125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 18483dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Rect bounds(s.active.transform.transform(layer->computeBounds())); 1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1850ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1851ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1852ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 18533dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const Transform tr(s.active.transform); 185422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza if (tr.preserveRects()) { 185522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transform the transparent region 185622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion = tr.transform(s.activeTransparentRegion); 18574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 185822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transformation too complex, can't do the 185922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transparent region optimization. 186022f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion.clear(); 18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1862ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1864ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 18653dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const int32_t layerOrientation = s.active.transform.getOrientation(); 18669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.alpha == 1.0f && !translucent && 1867ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1868ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1869ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1870ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1874ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1875ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1876ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1877ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1878ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1879ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 18884fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1891a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1894ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1900ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1902a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1903ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 19044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 19054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1911edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 191287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 19168b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1917a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1920a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1921a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1926edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 192887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 192992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 19304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 19314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 19324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 193392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 193492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 193587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 193687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 19376b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("handlePageFlip"); 19409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 19414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 194299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 19441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 19456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 194651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 194751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 194851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 194951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 195051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 195151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 195251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 195351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 195451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 195551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 195651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layers.size(); i<count ; i++) { 19571eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 19586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 19596b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 19606b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 19619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.push_back(layer.get()); 1962ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1963ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 19646b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1965ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1966ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 19676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 196851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner } 19699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 197087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 1971ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 19721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 197387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 19744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 19754da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 19763b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 19776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 19786b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 19796b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 19806b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 19819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (frameQueued && mLayersWithQueuedFrames.empty()) { 19826b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 19836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 19846b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 19856b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 19869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza return !mLayersWithQueuedFrames.empty(); 1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1989ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1990ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 19919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = true; 1992ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1993ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 199499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1995cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 199687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19987143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 19997143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 20007143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 20017143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 20027143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 20037143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 20049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Skipping display composition"); 20057143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 20067143316af216fa92c31a60d4407b707637382da1Dan Stoza } 20077143316af216fa92c31a60d4407b707637382da1Dan Stoza 20089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doDisplayComposition"); 20099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 201087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 201187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2012b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 20134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 2014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 20160f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 201729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 201829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 201929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 20204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 2021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 20220f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 202329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 2024df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 202595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 20260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 20274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 2028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 202929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 20304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 20314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (!doComposeSurfaces(hw, dirtyRegion)) return; 2036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20379c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 20384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 2039da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 2040da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 2041da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 2042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces( 20459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<const DisplayDevice>& displayDevice, const Region& dirty) 2046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposeSurfaces"); 20489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 20499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 20509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 20519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 oldColorMatrix; 20529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) && 20539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform); 20549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 20559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 20569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); 20579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 20589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool hasClientComposition = mHwc->hasClientComposition(hwcId); 20609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasClientComposition) { 20619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("hasClientComposition"); 2062a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 20639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) { 2064c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 20659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getDisplayName().string()); 20663f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 20673f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 20683f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 20693f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 20703f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 2071c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 2072a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2073a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 20749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId); 20759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasDeviceComposition) { 2076b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 2077b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 2078b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 20793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 2080b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 20819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->clearWithColor(0, 0, 0, 0); 2082b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 2083766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 20849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region bounds(displayDevice->getBounds()); 2085766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2086766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 2087766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 2088766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 20899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region letterbox(bounds.subtract(displayDevice->getScissor())); 2090766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2091766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 20929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Region region(displayDevice->undefinedRegion.merge(letterbox)); 2093766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2094766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 2095766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 2096766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2097b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 209887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 2099b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 21009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza drawWormhole(displayDevice, region); 2101b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 2102a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 2103f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 21049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 2105766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 2106f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 2107f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 21089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& bounds(displayDevice->getBounds()); 21099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& scissor(displayDevice->getScissor()); 2110f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 2111f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 2112f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 2113f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 21143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2115f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 21169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const uint32_t height = displayDevice->getHeight(); 21179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->setScissor(scissor.left, height - scissor.bottom, 21183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 2119f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 2120f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 212185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 21224b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 212385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 212485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 212585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 21264b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 21279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Rendering client layers"); 21289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& displayTransform = displayDevice->getTransform(); 21299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 213085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 21319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool firstLayer = true; 21329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 21339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region clip(dirty.intersect( 21349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Layer: %s", layer->getName().string()); 21369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Composition type: %s", 21379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza to_string(layer->getCompositionType(hwcId)).c_str()); 213885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza switch (layer->getCompositionType(hwcId)) { 21409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Cursor: 21419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Device: 21429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::SolidColor: { 2143ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 21449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getClearClientTarget(hwcId) && !firstLayer && 21459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->isOpaque(state) && (state.alpha == 1.0f) 21469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza && hasClientComposition) { 2147cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 2148cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->clearWithOpenGL(displayDevice, clip); 2150cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 215185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 215285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Client: { 21549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 215585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 2156a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza default: 2158da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 2159cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 21609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 21619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Skipping for empty clip"); 2162a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 21639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza firstLayer = false; 216485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 216585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 216685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 21679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 216885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 21699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 217085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 21719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 217285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 21734b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 21744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 2175f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 21769f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 21779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza getRenderEngine().setupColorTransform(oldColorMatrix); 21789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 21799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 2180f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 21819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->disableScissor(); 21823f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 2183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 218655801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 21873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 21883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 2189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 2192ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 21936710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 219413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 21951b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 21967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 21977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 21987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 21997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) { 22007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 22017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mCurrentState.layersSortedByZ.add(lbc); 22037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 22047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22057d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 220696f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 2207ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 22084f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 22097d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 221096f0819f81293076e652792794a961543e6750d7Mathias Agopian} 221196f0819f81293076e652792794a961543e6750d7Mathias Agopian 221292cd24e5f648175944deef5899258981807a9ca4Dan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) { 221396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 221492cd24e5f648175944deef5899258981807a9ca4Dan Stoza sp<Layer> layer = weakLayer.promote(); 221592cd24e5f648175944deef5899258981807a9ca4Dan Stoza if (layer == nullptr) { 221692cd24e5f648175944deef5899258981807a9ca4Dan Stoza // The layer has already been removed, carry on 221792cd24e5f648175944deef5899258981807a9ca4Dan Stoza return NO_ERROR; 221892cd24e5f648175944deef5899258981807a9ca4Dan Stoza } 221992cd24e5f648175944deef5899258981807a9ca4Dan Stoza 2220598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 2221598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (index >= 0) { 2222598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersPendingRemoval.push(layer); 2223598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersRemoved = true; 2224598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch setTransactionFlags(eTransactionNeeded); 2225598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return NO_ERROR; 2226598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch } 2227598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return status_t(index); 2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2230c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 2231dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 2232dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 2233dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 22343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 2240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 224199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 2244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22468b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 22478b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 22488b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 22498b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 22508b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 22517c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2252698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 225328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 22552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 22562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 22572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 22582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 22597c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 22602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 22612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 22627c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 22637c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 22647c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 22652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 22662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 22672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 22682d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 22692d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 22702d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2275b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2276b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2278698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2279698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2280d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2281d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2282d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2283d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2284d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2285d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2286d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2287d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2288097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2289d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2290d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2291d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2292d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2293d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2294d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2295d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2296d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2297698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2298386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 22992a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // If a synchronous transaction is explicitly requested without any changes, 23002a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // force a transaction anyway. This can be used as a flush mechanism for 23012a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // previous async transactions. 23022a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr if (transactionFlags == 0 && (flags & eSynchronous)) { 23032a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr transactionFlags = eTransactionNeeded; 23042a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr } 23052a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr 230628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2307386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 230828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2309698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2310386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2311386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2312386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 23132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 23142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 23162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2317386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 23182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2319386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2320386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2321386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2322386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 23232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 23242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2325386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2326386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2327cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2331e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2332e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 23339a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 23349a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 23359a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 23369a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 23389a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 23393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2342097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2343e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2344e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2346e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2347e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2348e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2349e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2350e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2351e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2352e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 235300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2354e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2355e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2356e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2357e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2358e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2359e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2360e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2361e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2362e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2363e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2364e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2365e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2366e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 236747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 236847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 236947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 237047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 237147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 237247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 237347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 237447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 237547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 237647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2377e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2378e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2379e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2380e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2381e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2382e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2383e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2385e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 238613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2387e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2388e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 238999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr bool geometryAppliesWithResize = 239099e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr what & layer_state_t::eGeometryAppliesWithResize; 2391e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 239299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) { 2393e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 239482364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr } 2395e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2396e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2397e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2398e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 239947db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayer(s.z) && idx >= 0) { 2400e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2401e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2402e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 24139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->setAlpha(s.alpha)) 2414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2420e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2421e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2424231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza if (what & layer_state_t::eFlagsChanged) { 2425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2427e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2428e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 242999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setCrop(s.crop, !geometryAppliesWithResize)) 2430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2432acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (what & layer_state_t::eFinalCropChanged) { 2433acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (layer->setFinalCrop(s.finalCrop)) 2434acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos flags |= eTraversalNeeded; 2435acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos } 2436e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 243947db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayerStack(s.layerStack) && idx >= 0) { 2440e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2441e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2444e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2445e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2446e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 24477dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza if (what & layer_state_t::eDeferTransaction) { 24487dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza layer->deferTransactionUntil(s.handle, s.frameNumber); 24497dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // We don't trigger a traversal here because if no other state is 24507dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // changed, we don't want this to cause any more work 24517dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 2452c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr if (what & layer_state_t::eOverrideScalingModeChanged) { 2453c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr layer->setOverrideScalingMode(s.overrideScalingMode); 2454c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // We don't trigger a traversal here because if no other state is 2455c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // changed, we don't want this to cause any more work 2456c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr } 2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 24614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 24620ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 24630ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 24644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 24654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 24686e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2469921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 24706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 24714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 24726e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 24738b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 24744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 24754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 24764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 24774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 24783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 24793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 24804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 24814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 24824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 24843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 24854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 24864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 24874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 24884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 24894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 24904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 24957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 24987d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza result = addClientLayer(client, *handle, *gbp, layer); 24997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 25007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 25017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 25027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 25037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 25044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 25084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 25094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 251292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 25188f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 25234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 25244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 25254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2526b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 25294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 25304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 25344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 25354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 25384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2539b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 25404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2541118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2542118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2543ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 25449a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 25456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 25466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 25476710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 25486710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 25496710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 25506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 25516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 25529a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 25539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 25549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 25559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 255613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25586710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 25596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 256092cd24e5f648175944deef5899258981807a9ca4Dan Stoza return removeLayer(layer); 2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2563b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2564b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 256513a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 256601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 256713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 256813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 256913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 257001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 257101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2572692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 257301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 257413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 25754c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 25764c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 257747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 257847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 257913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 258013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 25812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 25826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 25839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 25849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 25856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 258613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 258713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 258813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 258913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 259013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 259113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 259213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 259313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 259413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 259513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 259613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 259713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 259813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 259913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 260013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 260113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 26022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 26032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 26042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 26052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 26062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 26072c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 260813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 26092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 26102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2611c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2612c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2613c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 26142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 26152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 26162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 26172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 26182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2619c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 26202c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 2621f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn on the display 26222c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2623c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2624c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2625c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2626948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2627c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 2630b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 26312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 2632f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2633f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2634f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray param.sched_priority = 1; 2635f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { 2636f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_FIFO on display on"); 2637f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 26382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2639f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn off the display 2640f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2641f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { 2642f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_OTHER on display off"); 2643f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 2644f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2645c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2646948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2647948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2648cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2649cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2650cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2651c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 26522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 26532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 26552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 26562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2657b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 26612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2662db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2663db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 26642c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2665b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 26662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 26672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 26682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2669b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 26702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2671db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 26722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 26737306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 26749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 26752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2677db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 26782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2679db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2680b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2681b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2682b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 26832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2684db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2685b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2686b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2687b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2688b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 269299b49840d309727678b77403d6cc9f920111623fMathias Agopian 2693bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2694bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2695bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2696bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2697bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 269874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2699bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2701fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 27029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 27039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 2704fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 2705fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 27069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 2707fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 2708fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 2709fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 27109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 27119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 271282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 271382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 271425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 271525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 271625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 271725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 271825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 271974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 272035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 272125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 272225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 272325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 272425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 272582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 272674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 272735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 272882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 272925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 273025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 273125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 273225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 273374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 273435aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 273525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2736c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2737c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2738c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2739c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2740c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2741c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2742c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2743b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2744b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 2745b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 2746b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 2747b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2748b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 2749b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 275040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 275140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos if ((index < numArgs) && 275240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos (args[index] == String16("--fences"))) { 275340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos index++; 275440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos mFenceTracker.dump(&result); 275540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos dumpAll = false; 275640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos } 2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 275982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 276074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 276182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 276248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 276382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 276482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 276548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 276682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 276782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 276882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 276982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 277048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2771c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2772c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 277325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 277425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 277525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 277625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 277713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 277874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 277925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 278025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 278125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 278282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 278374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 278482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 278582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 278682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 278782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 278882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 278982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 279048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 27919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 27929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 279386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 27944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 27954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2796d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 27974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 27984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 27994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 28004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 280113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 28024b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2803d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 28044b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 280582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 280682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 280782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2808ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 280925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2810c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 281125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 281225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 281325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 281425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 281525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 281625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 281725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 281825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 281925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 282025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 282113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 282225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2823d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 282425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 282525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 28264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2827d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 282825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 282925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 28306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 28316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 28326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 28336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 28346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 28356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 28366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 28376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 28386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 28396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 28406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 28416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 28426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 28434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 28444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 28454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 28464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 28474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 28484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 28494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 28504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 28514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 28524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 28534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 28544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 28554803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 28564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 28574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 28584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 28594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 2860b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 2861b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 2862b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 2863b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { 2864b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[b] / 1e9; 2865b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2866b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[b]) / mTotalTime; 2867b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 2868b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 2869b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 2870b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; 2871b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2872b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; 2873b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 2874b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza NUM_BUCKETS - 1, bucketTimeSec, percent); 2875b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 2876b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2877e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName, 2878e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>&& history) { 2879e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 2880e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza auto& stats = mBufferingStats[layerName]; 2881e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& segment : history) { 2882e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (!segment.usedThirdBuffer) { 2883e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.twoBufferTime += segment.totalTime; 2884e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2885e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (segment.occupancyAverage < 1.0f) { 2886e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime += segment.totalTime; 2887e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else if (segment.occupancyAverage < 2.0f) { 2888e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime += segment.totalTime; 2889e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2890e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++stats.numSegments; 2891e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime += segment.totalTime; 2892e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2893e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 2894e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 2895e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const { 2896e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("Buffering stats:\n"); 2897e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append(" [Layer name] <Active time> <Two buffer> " 2898e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza "<Double buffered> <Triple buffered>\n"); 2899e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 2900e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza typedef std::tuple<std::string, float, float, float> BufferTuple; 2901e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::map<float, BufferTuple, std::greater<float>> sorted; 2902e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& statsPair : mBufferingStats) { 2903e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const char* name = statsPair.first.c_str(); 2904e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferingStats& stats = statsPair.second; 2905e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (stats.numSegments == 0) { 2906e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza continue; 2907e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2908e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = ns2ms(stats.totalTime) / 1000.0f; 2909e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float twoBufferRatio = static_cast<float>(stats.twoBufferTime) / 2910e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime; 2911e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float doubleBufferRatio = static_cast<float>( 2912e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime) / stats.totalTime; 2913e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float tripleBufferRatio = static_cast<float>( 2914e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime) / stats.totalTime; 2915e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza sorted.insert({activeTime, {name, twoBufferRatio, 2916e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza doubleBufferRatio, tripleBufferRatio}}); 2917e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2918e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& sortedPair : sorted) { 2919e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = sortedPair.first; 2920e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferTuple& values = sortedPair.second; 2921e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.appendFormat(" [%s] %.2f %.3f %.3f %.3f\n", 2922e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<0>(values).c_str(), activeTime, 2923e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<1>(values), std::get<2>(values), 2924e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<3>(values)); 2925e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2926e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("\n"); 2927e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 2928e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 2929e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 293074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 293174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 293282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 29333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 29343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 29353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 29363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 29373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 29383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 29393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 29403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 29413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 294282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 294382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 294482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 294582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 294682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 294782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2948bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 294982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 29504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 29514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 29523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 29533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 29544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 29553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 29564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 29574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 29584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 29594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 29604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 29613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2962ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 29633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2964ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2965ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2966ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 29679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 29689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 296941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 297041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 297141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 297224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 297324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 29749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, 29759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod()); 297641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 297741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 2978b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 2979b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 2980b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2981b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 2982b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza dumpBufferingStats(result); 2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 29854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 298682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 298782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 298882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 298982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 29903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 299186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 29923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 299382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 299413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 29953e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 299682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2997bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 299882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 29995f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 30005f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 30015f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 30023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 300386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 30043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30055f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 30065f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 300774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 30085f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 30095f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 30105f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 301182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 301282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 30131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 30143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 301574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 30163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30171b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 3018888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 30194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 3020ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 30213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 30223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 30233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 30243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 3026ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 3027ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 3028875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 30299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 30304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 30312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 30322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 303374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 303482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 303582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 3036c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 303782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 303882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 3039ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 3040ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 3041ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 304282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 304382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 3044c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 30459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1e9 / activeConfig->getVsyncPeriod(), 30469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiX(), 30479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiY(), 3048ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 304982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 305074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 305182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 305282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 305374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 305482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 305582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 305682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 305782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 305882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 305974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 3060e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3061e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3062e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza /* 3063e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza * HWC layer minidump 3064e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza */ 3065e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t d = 0; d < mDisplays.size(); d++) { 3066e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 3067e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza int32_t hwcId = displayDevice->getHwcDisplayId(); 3068e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 3069e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza continue; 3070e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3071e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3072e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.appendFormat("Display %d HWC layers:\n", hwcId); 3073e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza Layer::miniDumpHeader(result); 3074e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t l = 0; l < count; l++) { 3075e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<Layer>& layer(currentLayers[l]); 3076e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza layer->miniDump(result, hwcId); 3077e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3078e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3079e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 308082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 308182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 308282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 308382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 30843e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 308574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 30863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza bool hwcDisabled = mDebugDisableHWC || mDebugRegion; 30889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza result.appendFormat(" h/w composer %s\n", 30899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcDisabled ? "disabled" : "enabled"); 309074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 309182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 309282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 309382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 309482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 309582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 309682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 3097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 309913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 310048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 3101db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 310248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 310348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 310448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 310548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 310648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 310748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 310848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 310948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 311048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 311148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 311248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 311348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 311448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 3115cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 3116cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 311763f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 311863f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 311963f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 312063f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 312163f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 312263f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 312363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 312463f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 312563f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 312624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 312763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 312863f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 312963f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 313063f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 313163f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 313263f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 313363f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 313463f165fd6b86d04be94d4023e845e98560504a96Keun young Park 3135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 3136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 3139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 3140041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 3141698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 3142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 3143d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 3144d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 31452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 3146c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza case GET_HDR_CAPABILITIES: 3147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 3148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 3149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 3150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 3151a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 31523bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 315399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 3154e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 3155375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3156375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 3157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 31581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 31591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 31601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 31611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 31621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 31631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 31641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 31651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 316699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 316799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 3168e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 31691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 31701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 31711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 31721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 3173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 31751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 3177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 3178b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 317999ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 3180375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3181375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 3182375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 3183e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 3184375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 3186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 3188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 318901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 319035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 3191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 3193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 3194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 319553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 319653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 319953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3200cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3201cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 3202cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 3203e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 3204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 3205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 3206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 3207cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 32104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 32114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 32124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 321353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 321453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 321553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 321653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 321753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 321853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 3219a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 3220a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 3221a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 3222a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 3223a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 3224a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 3225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 322601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 3227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 3228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 3229b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 323012839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 3231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 3233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 32344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 32354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 3236ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 3237ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3238ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 3239ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 3240ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 3241ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 32429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 1: 32439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Protanomaly); 32449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 32459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 2: 32469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); 32479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 32489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 3: 32499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Tritanomaly); 32509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 32519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza default: 32529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::None); 32539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 3254ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3255ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 32569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Correction); 3257ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 32589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Simulation); 3259ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3260ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 3261ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 32629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 32639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 32649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 32659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 32669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 32679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 32689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 32699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 32709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 3271794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 32729f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza for (size_t j = 0; j < 4; j++) { 32739f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mColorMatrix[i][j] = data.readFloat(); 32749f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 32759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 32769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 32779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 32789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 32799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 32809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 32819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3283f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 3284f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 3285f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 3286645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 3287645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 3288f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 3289f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 3290ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 3291ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 3292ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 3293ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 3294ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 3295db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 3296db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3297db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3298db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3299db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3300db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 3301db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3302db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3303db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3304db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 33053cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza case 1021: { // Disable HWC virtual displays 33063cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza n = data.readInt32(); 33073cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza mUseHwcVirtualDisplays = !n; 33083cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza return NO_ERROR; 33093cf4bfe2368020b50a3e22360910b6af6590c5beDan Stoza } 3310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 3313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 331553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 331687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 331799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 331853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 331953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 332059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 33212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 33222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 332359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 33242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 33252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 33262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 3327b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 3328b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 3329b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 3330b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 33312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 33322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 3333b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 3334b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 3335b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 3336b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3337b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 3338b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 3339b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 3340b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 3341b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3342b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 3343b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 3344b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 3345b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 3346b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 33472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 33482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 33492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 33502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 33512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 3352b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 33532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 33542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 33552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 33562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 33572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 33582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 33592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 33602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 33612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 33622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3363b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 3364b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 3365b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 33662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 33672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 3368c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 33692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 33702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 33712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 33722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 3373b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 3374b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 3375b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 3376b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 33772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 33782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 33792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 3380b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 3381b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 3382b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 33832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 33842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 33852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 3386c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 33872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 33882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 33892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3390b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 33912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 33922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 33932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 3394b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 3395b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 3396b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 3397b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 3398097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 33992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 3400b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 34012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 34022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 34032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 34042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 3406b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 3407b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 3408b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 340953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos result(NO_ERROR), 3410b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 341153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos exitRequested(false), 341253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos code(0), 341353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos data(NULL), 341453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos reply(NULL) 3415b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 3416b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 3417b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 34182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 34192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 34202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 34212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 34222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 34232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 34242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 3425b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 34262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 3427aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 34282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 3429b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 3430b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 3431b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 34322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 34332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 34342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 34352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 34382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3439c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3440c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3441c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 34422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 34432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 34442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 34452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 34462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 34472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 34482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 34495ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 34505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 34515ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 3452b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder(); 34535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 3454c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 3455c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 3456c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 3457c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 3458c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3459c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3460c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3461c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3462c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3463c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3464c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3465c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3466c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3467c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3468c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3469c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3470c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3471c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3472c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3473c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3474c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 34752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 34762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 34772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 34782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3479c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 34802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 34812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3482c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3483c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 34842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 3485b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot; 34862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 34872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 34882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 34892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3490c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3491c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3492b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, 3493b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos Transform::orientation_flags rotation, 3494b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 34952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3496c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 34972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3498c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3499b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos rotation(rotation), result(PERMISSION_DENIED), 3500b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos isLocalScreenshot(isLocalScreenshot) 35012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 35022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 35032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 35042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 35052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 35062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 35072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 35082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3509c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3510c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3511b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotation, isLocalScreenshot); 3512097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 35132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 35142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 35152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 35162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 35182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 35232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 35242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 35252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3526c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3527b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotationFlags, isLocalScreenshot); 35282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 35302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 35312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 35322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 35332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3534118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3535118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3536180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3537180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3538180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3539c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3540180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 3541c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3542180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3543180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 35443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3545180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3546180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 354789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 354889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 354989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 35500e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 3551180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3552c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3553c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3554c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3555c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3556c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3557c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3558c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3559c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3560c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3561c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3562c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3563be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3564be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3565c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3566c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3567c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3568c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3569be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3570be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3571c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3572c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3573180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 35743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3575180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3576180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3577c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3578c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 35793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3580180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3581180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 35823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3583180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3584180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3585180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3586180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3587180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 35881eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3589180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3590180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3591180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3592180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3593c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3594180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3595180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3596180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3597180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3598180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3599180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3600931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3601180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3602180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3603180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3607c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3608c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3609b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, Transform::orientation_flags rotation, 3610b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 361174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3612fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3613fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3614180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 36153502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_w = hw->getWidth(); 36163502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_h = hw->getHeight(); 36173502416204d9dbd905012ee586d8bd145323809fDan Stoza 36183502416204d9dbd905012ee586d8bd145323809fDan Stoza if (rotation & Transform::ROT_90) { 36193502416204d9dbd905012ee586d8bd145323809fDan Stoza std::swap(hw_w, hw_h); 36203502416204d9dbd905012ee586d8bd145323809fDan Stoza } 3621180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3622180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3623180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3624180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3625180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3626180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3627180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3628180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3629180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3630180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3631b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool secureLayerIsVisible = false; 3632b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const LayerVector& layers(mDrawingState.layersSortedByZ); 3633b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const size_t count = layers.size(); 3634b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos for (size_t i = 0 ; i < count ; ++i) { 3635b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const sp<Layer>& layer(layers[i]); 3636b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const Layer::State& state(layer->getDrawingState()); 3637b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ && 3638b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos state.z <= maxLayerZ && layer->isVisible() && 3639b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos layer->isSecure()) { 3640b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos secureLayerIsVisible = true; 3641b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3642b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3643b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 3644b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (!isLocalScreenshot && secureLayerIsVisible) { 3645b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos ALOGW("FB is protected: PERMISSION_DENIED"); 3646b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos return PERMISSION_DENIED; 3647b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3648b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 36490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 36500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 365183cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 3652605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 3653605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Put the screenshot Surface into async mode so that 3654605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Layer::headFenceHasSignaled will always return true and we'll latch the 3655605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // first buffer regardless of whether or not its acquire fence has 3656605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // signaled. This is needed to avoid a race condition in the rotation 3657605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // animation. See b/30209608 3658605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos sur->setAsyncMode(true); 3659605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 36600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 366174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 36625a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 36635a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine if (result == NO_ERROR) { 36643ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 36653ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 36662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 36670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 36680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 36694ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 36700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 36710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 36722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 36730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 36740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 36750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 36760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 36770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 36780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 36790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3680866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 36810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 36820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 36830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 36840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 36850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 36863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 36873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 36883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 36893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 36900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 36910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 36920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 36930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3694c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3695c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3696c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3697d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3698866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3699866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3700866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3701866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3702866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3703866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 37049707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 37059707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3706866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3707866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3708866399093f9f60e7305f291e688abb456bace710Riley Andrews } 37092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3710866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3711866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3712866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3713866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3714866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3715866399093f9f60e7305f291e688abb456bace710Riley Andrews } 37162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3717866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3718866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3719866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3720866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3721866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3722866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3723866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3724866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3725866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3726866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3727866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3728866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3729866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3730866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 37312d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3732866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 37332d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 37342d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3735d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3736d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3737d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3738d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3739d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3740d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3741d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3742d555684cb36dfb959694db76962e570184f98838Mathias Agopian 37430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 37440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 37450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 3746f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu window->cancelBuffer(window, buffer, syncFd); 3747f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu buffer = NULL; 37480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 37490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 37500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 37510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 37520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 375374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3754f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu if (buffer) { 3755f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu // queueBuffer takes ownership of syncFd 3756f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu result = window->queueBuffer(window, buffer, syncFd); 3757f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu } 375874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 37590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 37600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 376174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 37620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 376374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 376474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 376574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 376674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 376774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3768d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3769d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3770fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3771d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3772d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3773d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3774fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3775fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3776fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3777fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3778fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3779fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3780fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3781fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3782fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3783fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3784fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3785fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3786fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3787fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 37889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", 3789fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3790fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3791fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3792fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3793fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3794fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3795fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 3796ce796e78a57018f186b062199c75d94545318acaPablo Ceballosbool SurfaceFlinger::getFrameTimestamps(const Layer& layer, 3797ce796e78a57018f186b062199c75d94545318acaPablo Ceballos uint64_t frameNumber, FrameTimestamps* outTimestamps) { 3798ce796e78a57018f186b062199c75d94545318acaPablo Ceballos return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps); 3799ce796e78a57018f186b062199c75d94545318acaPablo Ceballos} 3800ce796e78a57018f186b062199c75d94545318acaPablo Ceballos 38011b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 38021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3803921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3804921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3805921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3806921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 380713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3808921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3809921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3810921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3811921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3813be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 381413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 381513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3816be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 38171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 38181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3819be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3820be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3821be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 38221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 38231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3824be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3825be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3826be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3827be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3828921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3829921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3830921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3831921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 38323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 383353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos : type(DisplayDevice::DISPLAY_ID_INVALID), 383453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos layerStack(DisplayDevice::NO_LAYER_STACK), 383553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos orientation(0), 383653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos width(0), 383753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos height(0), 383853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos isSecure(false) { 383953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos} 384053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos 384153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo CeballosSurfaceFlinger::DisplayDeviceState::DisplayDeviceState( 384253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDevice::DisplayType type, bool isSecure) 384353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos : type(type), 384453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos layerStack(DisplayDevice::NO_LAYER_STACK), 384553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos orientation(0), 384653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos width(0), 384753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos height(0), 384853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos isSecure(isSecure) { 3849da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3850da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3851b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 38527303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3853b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 385496f0819f81293076e652792794a961543e6750d7Mathias Agopian 3855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 38563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 38573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 38583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 38593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 38603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 38613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 38623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 38633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 38643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3865