SurfaceFlinger.cpp revision 2047fae0cfed99c425dc7333f31d309e5b8ee1ba
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza// #define LOG_NDEBUG 0 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 191c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 21921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 24c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju#include <mutex> 2563f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 2686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h> 27b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h> 28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 29921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 327823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 4067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h> 41c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 46e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 47392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 53cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 570a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h> 581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 60921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 61ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 68faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 69d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 70d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 76a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 82ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 83875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 91fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 92ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 93ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1190a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12799b49840d309727678b77403d6cc9f920111623fMathias Agopian 12899b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12999b49840d309727678b77403d6cc9f920111623fMathias Agopian 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1314f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 137875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 1399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mBuiltinDisplays(), 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 1419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid(false), 1424b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1448afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14573d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 146a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 151ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 152ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 153468051e20be19130572231266db306396a56402bIrvel mInterceptor(), 1544a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mPrimaryDispSync("PrimaryDispSync"), 155faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 156948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasColorMatrix(false), 158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff(false), 159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets(), 160b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime(0), 161b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime(0) 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 163a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1678afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 168b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 16950210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 170b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1738afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1748afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1758afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 17763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 17863f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 17963f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 18063f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1818afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 182c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 183c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 184c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza 185c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza property_get("debug.sf.disable_backpressure", value, "0"); 186c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza mPropagateBackpressure = !atoi(value); 187c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation"); 1888cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 1898cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza property_get("debug.sf.disable_hwc_vds", value, "0"); 1908cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !atoi(value); 1918cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays"); 19263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard 19363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard property_get("ro.sf.disable_triple_buffer", value, "0"); 19463a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard mLayerTripleBufferingDisabled = !atoi(value); 19563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering"); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 205a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 206a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 207a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 210c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 21299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 21399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 21413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 21513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 21699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 21799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 218a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 21999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 22099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2217e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 22496f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 22596f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 22696f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 22796f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 232dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 233dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 244c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit DisplayToken(const sp<SurfaceFlinger>& flinger) 245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 25253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure); 2538dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 255ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayCreation(info); 256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2636c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2646c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2656c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2666c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2676c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 273ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayDeletion(info.displayId); 2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2766c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 278692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 2799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("createBuiltinDisplayLocked(%d)", type); 280692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 281692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 282692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 283692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 28453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(type, true); 285692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 286ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayCreation(info); 287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 288692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2909e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 291e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 294692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 3009a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 3019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 307a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 3083330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 3091f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3101f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 3111f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 3121f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 3131f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 3151f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 3161f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3171f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 318a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 319a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 320a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 3210a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato 3220a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato const int LOGTAG_SF_STOP_BOOTANIM = 60110; 3230a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, 3240a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 328921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 331921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 338921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 339921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 341921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 342921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3455167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3464a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* name) : 3474a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mName(name), 3480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3504a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncOnLabel(String8::format("VsyncOn-%s", name)), 3514a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncEventLabel(String8::format("VSYNC-%s", name)), 352db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mDispSync(dispSync), 353db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallbackMutex(), 354db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallback(), 355db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mVsyncMutex(), 356db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset(phaseOffset), 357db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled(false) {} 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 362db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3644a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray status_t err = mDispSync->addEventListener(mName, mPhaseOffset, 365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3705167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3785167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 379faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 380db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled = enable; 381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza virtual void setPhaseOffset(nsecs_t phaseOffset) { 389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Normalize phaseOffset to [0, period) 392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza auto period = mDispSync->getPeriod(); 393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset %= period; 394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (phaseOffset < 0) { 395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're here, then phaseOffset is in (-period, 0). After this 396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // operation, it will be in (0, period) 397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset += period; 398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset = phaseOffset; 400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're not enabled, we don't need to mess with the listeners 402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (!mEnabled) { 403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return; 404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Remove the listener with the old offset 407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza status_t err = mDispSync->removeEventListener( 408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error unregistering vsync callback: %s (%d)", 411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Add a listener with the new offset 4154a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray err = mDispSync->addEventListener(mName, mPhaseOffset, 416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 417db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 418db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error registering vsync callback: %s (%d)", 419db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 421db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 422db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 426faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 427db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 429a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4300a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 4310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 4325167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 4330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 436faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4414a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* const mName; 4424a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 443faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 444faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4450a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 4465167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 4475167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 4480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 449faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 450db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 451db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mCallbackMutex; // Protects the following 452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mVsyncMutex; // Protects the following 455db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza nsecs_t mPhaseOffset; 456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza bool mEnabled; 457faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 459c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource { 460c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic: 461c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju InjectVSyncSource() {} 462c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 463c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual ~InjectVSyncSource() {} 464c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 465c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 466c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 467c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mCallback = callback; 468c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 469c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 470c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void onInjectSyncEvent(nsecs_t when) { 471c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 472c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mCallback->onVSyncEvent(when); 473c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 474c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 475c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setVSyncEnabled(bool) {} 476c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setPhaseOffset(nsecs_t) {} 477c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 478c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate: 479c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::mutex mCallbackMutex; // Protects the following 480c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju sp<VSyncSource::Callback> mCallback; 481c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}; 482c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 483faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 484a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 485a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 486a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza { // Autolock scope 4889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 4899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 4909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize EGL for the default display 4919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 4929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza eglInitialize(mEGLDisplay, NULL, NULL); 493692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 4949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // start the EventThread 4959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, true, "app"); 497ab04685578b254c2eaf43bf5da85e5e922787825Irvel mEventThread = new EventThread(vsyncSrc, *this, false); 4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sfVsyncPhaseOffsetNs, true, "sf"); 500ab04685578b254c2eaf43bf5da85e5e922787825Irvel mSFEventThread = new EventThread(sfVsyncSrc, *this, true); 5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEventQueue.setEventThread(mSFEventThread); 502a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 503acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray // set SFEventThread to SCHED_FIFO to minimize jitter 50441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray struct sched_param param = {0}; 50535520634e298f53bd8433825640d6999760f25b3Tim Murray param.sched_priority = 2; 50641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { 50741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray ALOGE("Couldn't set SCHED_FIFO for SFEventThread"); 50841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray } 50941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray 5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Get a RenderEngine for the given display / config (can't fail) 5119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine = RenderEngine::create(mEGLDisplay, 5129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza HAL_PIXEL_FORMAT_RGBA_8888); 5139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 514f9481058101c4e2b38c74048feac383664691d03Saurabh Shah 5159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Drop the state lock while we initialize the hardware composer. We drop 5169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // the lock because on creation, it will call back into SurfaceFlinger to 5179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize the primary display. 5189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc = new HWComposer(this); 5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this)); 520b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 522875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 523875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 524875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 525a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 526da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 527da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 528da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 5299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // make the GLContext current so that we can create textures when creating 5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Layers (which may happens before we render something) 531a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 532a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 533d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 534d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 535d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 53692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 53792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 5388630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 53913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 54013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 54113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 5424e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza mRenderEngine->primeCache(); 5434e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza 544a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 545a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Done initializing"); 5483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 5493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 550a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 551a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 552a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 553a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 554a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 555a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 556875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 557875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 558a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 559a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 560875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 561875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 562a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 563a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 565d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 566582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 5672adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 568134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 569097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 5706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 571134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 572134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 573069b365163470d2736eb6f591c354d208b5da23bBrian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps( 5743890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson std::vector<FrameEvent>* outSupported) const { 575069b365163470d2736eb6f591c354d208b5da23bBrian Anderson *outSupported = { 5763890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::REQUESTED_PRESENT, 5773890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::ACQUIRE, 578f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson FrameEvent::LATCH, 5793890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::FIRST_REFRESH_START, 580f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson FrameEvent::LAST_REFRESH_START, 5813890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::GL_COMPOSITION_DONE, 5823d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson getHwComposer().presentFenceRepresentsStartOfScanout() ? 5833890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::DISPLAY_PRESENT : FrameEvent::DISPLAY_RETIRE, 584f7fd56a649f07133ad78d31eb5d3ae7a4e95d522Brian Anderson FrameEvent::DEQUEUE_READY, 5853890c3995c4a52439844faeb80b5503d42b977d8Brian Anderson FrameEvent::RELEASE, 586069b365163470d2736eb6f591c354d208b5da23bBrian Anderson }; 587069b365163470d2736eb6f591c354d208b5da23bBrian Anderson return NO_ERROR; 588069b365163470d2736eb6f591c354d208b5da23bBrian Anderson} 589069b365163470d2736eb6f591c354d208b5da23bBrian Anderson 5907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 59223e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa if ((configs == NULL) || (display.get() == NULL)) { 5937f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5967aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 5977aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 5987aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 599692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 6009e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 601692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 6021604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 6031604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 6041604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6051604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6061604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6071604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 6081604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 609c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 6108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 6128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 6138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 6148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 6158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 6168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 6178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 6188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 6208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 6228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 6238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 6248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 6258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 6268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 6271604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (const auto& hwConfig : getHwComposer().getConfigs(type)) { 6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float xdpi = hwConfig->getDpiX(); 6349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float ydpi = hwConfig->getDpiY(); 6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 6407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 6417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 6467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 6477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 6487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 6517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 6557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 6577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 6587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 6597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 6601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.w = hwConfig->getWidth(); 6639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.h = hwConfig->getHeight(); 6647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 6657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 6669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.fps = 1e9 / hwConfig->getVsyncPeriod(); 66791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 6689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 66991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 67091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 67191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 67291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 67391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 67491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 67591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 67691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 67791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 67891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 67991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 68091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 6819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.presentationDeadline = hwConfig->getVsyncPeriod() - 6829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 6837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 6857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 68728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright configs->push_back(info); 6888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6898b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6907f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6917f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 692dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 69389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 69467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 69567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 69667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 69767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 69867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 69967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 70067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 70167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 70267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 70367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 70467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 70567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 7079f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong if (display == NULL) { 7089f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong ALOGE("%s : display is NULL", __func__); 7099f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong return BAD_VALUE; 7109f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong } 71124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza sp<DisplayDevice> device(getDisplayDevice(display)); 71224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 71324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 71424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 71524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 7167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 717dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 7186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 7226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 7356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 7366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 7376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 7396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 7406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 7416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 7426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 7436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 7446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 7456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 7466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 7476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 7487306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 7497306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 750784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 7519ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 7527306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 75328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 7547306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 7556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 7566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 7576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 7587306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 7596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 7606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 7616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 7626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 7636c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 7646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 7666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 7686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 7696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 770888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 771c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display, 77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t>* outColorModes) { 77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if ((outColorModes == nullptr) || (display.get() == nullptr)) { 77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return BAD_VALUE; 77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (!display.get()) { 77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NAME_NOT_FOUND; 78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = NAME_NOT_FOUND; 78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (display == mBuiltinDisplays[i]) { 78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright type = i; 78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright break; 78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type < 0) { 79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return type; 79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type); 79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright outColorModes->clear(); 79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); 79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) { 80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> device(getDisplayDevice(display)); 80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (device != nullptr) { 80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return device->getActiveColorMode(); 80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return static_cast<android_color_mode_t>(BAD_VALUE); 80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw, 81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) { 81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright this); 81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = hw->getDisplayType(); 81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t currentMode = hw->getActiveColorMode(); 81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 81628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mode == currentMode) { 81728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode); 81828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 81928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 82028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 82128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 82228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Trying to set config for virtual display"); 82328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 82428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 82528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 82628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright hw->setActiveColorMode(mode); 82728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright getHwComposer().setActiveColorMode(type, mode); 82828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 82928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 83028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display, 83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t colorMode) { 83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright class MessageSetActiveColorMode: public MessageBase { 83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright SurfaceFlinger& mFlinger; 83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<IBinder> mDisplay; 83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mMode; 83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright public: 83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp, 83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) : 84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger(flinger), mDisplay(disp) { mMode = mode; } 84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright virtual bool handler() { 84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t> modes; 84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.getDisplayColorModes(mDisplay, &modes); 84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes); 84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mMode < 0 || !exists) { 84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode, 84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mDisplay.get()); 84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (hw == nullptr) { 85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set active color mode = %d for null display %p", 85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode, mDisplay.get()); 85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 85528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Attempt to set active color mode= %d for virtual display", 85628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode); 85728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else { 85828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.setActiveColorModeInternal(hw, mMode); 85928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 86028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 86128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 86228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright }; 86328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode); 86428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright postMessageSync(msg); 86528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 86628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 867c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 868d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 869d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 870d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 871d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 872d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 873d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 874d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 875d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 876d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 877d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 878d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 879d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 880c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, 881c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza HdrCapabilities* outCapabilities) const { 882c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza Mutex::Autolock _l(mStateLock); 883c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 884c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza sp<const DisplayDevice> displayDevice(getDisplayDevice(display)); 885c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (displayDevice == nullptr) { 886c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get()); 887c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 888c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 889c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 890c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::unique_ptr<HdrCapabilities> capabilities = 891c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); 892c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (capabilities) { 893c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::swap(*outCapabilities, *capabilities); 894c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } else { 895c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 896c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 897c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 898c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return NO_ERROR; 899c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza} 900c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 901c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) { 902c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable == mInjectVSyncs) { 903c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 904c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 905c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 906c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable) { 907c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 908c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections enabled"); 909c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mVSyncInjector.get() == nullptr) { 910c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector = new InjectVSyncSource(); 911ab04685578b254c2eaf43bf5da85e5e922787825Irvel mInjectorEventThread = new EventThread(mVSyncInjector, *this, false); 912c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 913c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mInjectorEventThread); 914c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } else { 915c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 916c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections disabled"); 917c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mSFEventThread); 918c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector.clear(); 919c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 920c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 921c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 922c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 923c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) { 924c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (!mInjectVSyncs) { 925c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGE("VSync Injections not enabled"); 926c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return BAD_VALUE; 927c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 928c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) { 929c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("Injecting VSync inside SurfaceFlinger"); 930c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector->onInjectSyncEvent(when); 931c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 932c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 933c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 934c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 935d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 936d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 937d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 9388aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 939bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 940bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 94299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 94399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 94499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 94599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 94899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 95299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 95399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 95699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 95799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 95899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 95999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 960c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 96199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 96299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 96399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 96499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 965c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 96699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 96799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 96899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 96999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 97099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 97199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9734f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 9744f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 9754f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 9764f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 97799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 979faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 980faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 981948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 982faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 983d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 984d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 985faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 98643601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 987faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 988faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 989948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 990faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 991faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 992948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 993948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 994948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 9950a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // Hardware vsync is not currently available, so abort the resync 9960a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // attempt for now 997948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 998948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 999948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 10009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 10019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 1002faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 1005faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1006faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 1008d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 1009d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 1010faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 1011faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1012faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1014948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 1015faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1016faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 1017d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 1018d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 1019faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 1020faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 1021faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1022948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 1023948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 1024948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1025faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1026faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 10274a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() { 10284a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray static constexpr nsecs_t kIgnoreDelay = ms2ns(500); 10294a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray if (systemTime() - mLastSwapTime > kIgnoreDelay) { 10300a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza resyncToHardwareVsync(false); 10314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray } 10324a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray} 10334a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 10349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) { 1035d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 1036faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1037d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 1038d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1039d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 1040d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 1041faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1042148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 1043d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 1044d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 1045d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 1046d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 1047d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 1048d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 1049148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 1050148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) { 10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false"); 10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (disp == DisplayDevice::DISPLAY_PRIMARY) { 10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock lock(mStateLock); 10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // All non-virtual displays are currently considered secure. 10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool isSecure = true; 10589e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t type = DisplayDevice::DISPLAY_PRIMARY; 10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY); 10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza wp<IBinder> token = mBuiltinDisplays[type]; 10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferProducer> producer; 10649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferConsumer> consumer; 10659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new GraphicBufferAlloc()); 10679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, 10699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, consumer); 10709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<DisplayDevice> hw = new DisplayDevice(this, 10719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs, 10729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer, mRenderEngine->getEGLConfig()); 10739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mDisplays.add(token, hw); 10749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 10759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto type = DisplayDevice::DISPLAY_EXTERNAL; 10769e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 1077692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 10789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(type); 10799e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 1080692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 1081692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 10829e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 10839e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 10849e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 10859e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 10863ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 10878630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10888630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) { 1090faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 10919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza getHwComposer().setVsyncEnabled(disp, 10929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); 10938630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10948630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 10961c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 109799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 10986b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 10995018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza bool frameMissed = !mHadClientComposition && 11005018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence != Fence::NO_FENCE && 11015018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence->getSignalTime() == INT64_MAX; 11025018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); 1103c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza if (mPropagateBackpressure && frameMissed) { 11045018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza signalLayerUpdate(); 11055018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza break; 11065018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza } 11075018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza 11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 11105878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 11116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 11125878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 11135878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 11145878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 11156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 11166b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 11186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 11206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 11216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 11226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11266b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 1127c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard uint32_t transactionFlags = peekTransactionFlags(); 11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 112987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 11306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 11314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 11334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11356b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 1136cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 11376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 11384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 11393a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 11404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 114214cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 114340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 114405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 1145d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson preComposition(refreshStartTime); 114605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza rebuildLayerStacks(); 114705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza setUpHWComposer(); 114805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doDebugFlashRegions(); 114905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doComposition(); 1150d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson postComposition(); 115105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 115211d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 1153bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza 1154bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = false; 1155bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1156bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1157bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = mHadClientComposition || 1158bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); 1159bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza } 116014cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 11619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.clear(); 1162cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1163cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1164cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 1165cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 1166cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 1167cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 1169cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1170cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 1171cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1172cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 11732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1174cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1175cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1176cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 1177cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 1178cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 1179cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1180cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 1181cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 11823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 11833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 11843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1185da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1187cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1188cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1189cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1190cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 1191cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1192cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 1193cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 1194cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1195bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 11969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 11977bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 11987bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 11997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 12007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 12017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 12027bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 12039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 12049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 1205bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1207cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1208d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime) 1209cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 12109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("preComposition"); 12129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 12142047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 12152047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (layer->onPreComposition(refreshStartTime)) { 1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 1217cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 12182047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 12192047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 1220cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 1221cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 1222cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1223cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1224a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1225d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::postComposition() 1226cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 12279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postComposition"); 12299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 12303546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson // Release any buffers which were replaced this frame 1231f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson nsecs_t dequeueReadyTime = systemTime(); 12323546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson for (auto& layer : mLayersWithQueuedFrames) { 1233f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson layer->releasePendingBuffer(dequeueReadyTime); 12343546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson } 12353546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson 1236d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 12373d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 12383d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::shared_ptr<FenceTime> glCompositionDoneFenceTime; 12393d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) { 12403d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = 12413d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::make_shared<FenceTime>(hw->getClientTargetAcquireFence()); 12423d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); 12433d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } else { 12443d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = FenceTime::NO_FENCE; 12453d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } 12463d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mGlCompositionDoneTimeline.updateSignalTimes(); 12473d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 12483d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson sp<Fence> displayFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 12493d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson auto displayFenceTime = std::make_shared<FenceTime>(displayFence); 12503d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mDisplayTimeline.push(displayFenceTime); 12513d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mDisplayTimeline.updateSignalTimes(); 12523d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 12533d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson const std::shared_ptr<FenceTime>* presentFenceTime = &FenceTime::NO_FENCE; 12543d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson const std::shared_ptr<FenceTime>* retireFenceTime = &FenceTime::NO_FENCE; 12553d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (mHwc->presentFenceRepresentsStartOfScanout()) { 12563d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson presentFenceTime = &displayFenceTime; 12573d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } else { 12583d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson retireFenceTime = &displayFenceTime; 12593d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } 12602047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 12612047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, 12622047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr *presentFenceTime, *retireFenceTime); 1263e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (frameLatched) { 12642047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr recordBufferingStats(layer->getName().string(), 12652047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->getOccupancyHistory(false)); 1266e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 12672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 12684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 12693d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (displayFence->isValid()) { 12703d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (mPrimaryDispSync.addPresentFence(displayFence)) { 1271faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1272faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1273948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1274faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1275faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1276faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 12775167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 12782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1279faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1280faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1281faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1282faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 12834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 12844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 12854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 12863d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson if (displayFenceTime->isValid()) { 12873d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mAnimFrameTracker.setActualPresentFence( 12883d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::move(displayFenceTime)); 12894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 12904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 12914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 12929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nsecs_t presentTime = 12939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 12944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 12954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 12964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 12974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1298b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1299b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1300b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1301b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1302b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1303b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1304b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1305b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1306b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1307b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t period = mPrimaryDispSync.getPeriod(); 1308b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t elapsedTime = currentTime - mLastSwapTime; 1309b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza size_t numPeriods = static_cast<size_t>(elapsedTime / period); 1310b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (numPeriods < NUM_BUCKETS - 1) { 1311b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[numPeriods] += elapsedTime; 1312b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1313b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; 1314b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1315b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime += elapsedTime; 1316b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1317b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime = currentTime; 1318cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1319cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1320cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 13219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 13229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("rebuildLayerStacks"); 13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1324cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 132552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1326cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 132787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 132887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 1329ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1331ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 1332ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Vector<sp<Layer>> layersSortedByZ; 13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<DisplayDevice>& displayDevice(mDisplays[dpy]); 13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& tr(displayDevice->getTransform()); 13369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect bounds(displayDevice->getBounds()); 13379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->isDisplayOn()) { 13382047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr computeVisibleRegions( 13399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getLayerStack(), dirtyRegion, 13409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza opaqueRegion); 13417e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 13422047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 13431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 13449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.layerStack == displayDevice->getLayerStack()) { 1345a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 1346a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 1347a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 1348a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 1349ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 13509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 13519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Clear out the HWC layer if this layer was 13529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // previously visible, but no longer is 13539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(displayDevice->getHwcDisplayId(), 13549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nullptr); 1355ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 135687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 13572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 13583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 13599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); 13609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.set(bounds); 13619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.subtractSelf( 13629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza tr.transform(opaqueRegion)); 13639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->dirtyRegion.orSelf(dirtyRegion); 13643b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 13653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1366cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 13673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1368cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 13699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 13709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("setUpHWComposer"); 13719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1372028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1373b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1374b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1375b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1376b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1377b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1378b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1379b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1380b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1381b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1382b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1383b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1384b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1385b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1386b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1387b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1388b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1389b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1390b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1391b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1392b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1393b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 13947143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1395b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1396b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1397b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1398b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1399028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1400028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 14019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // build the h/w work list 14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (CC_UNLIKELY(mGeometryInvalid)) { 14039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = false; 14049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<const DisplayDevice> displayDevice(mDisplays[dpy]); 14069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Vector<sp<Layer>>& currentLayers( 14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getVisibleLayersSortedByZ()); 14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool foundLayerWithoutHwc = false; 1411ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr for (size_t i = 0; i < currentLayers.size(); i++) { 1412ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr auto const& layer = currentLayers[i]; 14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!layer->hasHwcLayer(hwcId)) { 14149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = mHwc->createLayer(hwcId); 14159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcLayer) { 14169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(hwcId, std::move(hwcLayer)); 14179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 14189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza foundLayerWithoutHwc = true; 14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 1421a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1422a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1423a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1424ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr layer->setGeometry(displayDevice, i); 14259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (mDebugDisableHWC || mDebugRegion) { 14269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 142703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 142803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 142903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 143003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 14319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 143203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 14339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 14359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Set the per-frame data 14379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 14399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 14409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId < 0) { 14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 14429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (colorMatrix != mPreviousColorMatrix) { 14449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza status_t result = mHwc->setColorTransform(hwcId, colorMatrix); 14459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " 14469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza "display %zd: %d", displayId, result); 14479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 14489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 14499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setPerFrameData(displayDevice); 145038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 145152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 14529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 14539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mPreviousColorMatrix = colorMatrix; 14549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14567bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 14577bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 14587bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 14597bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 14607bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 14617bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 14629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 14639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 14649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1465cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 146652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1467cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1468cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 14699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposition"); 14709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 147152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 147292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 14742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1475cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1476cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 147702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 147802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 147902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 148002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1481cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1482cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1483cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 148487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 14854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 148652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1491841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 14929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postFramebuffer"); 1493b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1496c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 14979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 14997bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 15007bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 15017bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 15029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 15039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 1504a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard mHwc->presentAndGetReleaseFences(hwcId); 15059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 15062dc3be88bd85791556ab0e6df6a080989886749eDan Stoza displayDevice->onSwapBuffersCompleted(); 1507b2c838b7add20c4515966a80de809b0a1d315001Season Li displayDevice->makeCurrent(mEGLDisplay, mEGLContext); 15089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 15099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> releaseFence = Fence::NO_FENCE; 15109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) { 15119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = displayDevice->getClientTargetAcquireFence(); 15129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 15139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = layer->getHwcLayer(hwcId); 15149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer); 151552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 15169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->onLayerDisplayed(releaseFence); 15179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 15189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 15199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->clearReleaseFences(hwcId); 1520ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1521e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1522e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1523a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1524a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 15256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 15266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 15276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 15286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 15296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 153287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1534841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1535841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 15367cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 15377cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 15387cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 15397cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 15407cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 15417cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1542ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1543ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1544ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1545ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1546ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1547ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1548ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1549ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1550ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1551ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 155387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1554ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1555ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1556ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1557ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1558ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 15593d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 156187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 15623d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 15633d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15657dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // Notify all layers of available frames 15662047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([](Layer* layer) { 15672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->notifyAvailableFrames(); 15682047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 15697dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 15762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 15782047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (!trFlags) return; 1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 15832047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 15873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 159192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 159292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 159392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1594e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1595e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 159692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 159892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 159993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 160092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 160192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 160292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 160392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 160492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 160592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1606e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1607e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 160892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 16093ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 161027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 161127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 161227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 161302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1614875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 161502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 161602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 161702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 16189e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 16197adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 162002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 162192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 162292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 162392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 162492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 162592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1626e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 16273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1628097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1629097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 16301474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1631e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 163293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 163393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 163493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 163502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 163602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 163702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 163893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 163993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 164093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 164193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 164293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 164392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 164493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1645db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 164693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 164793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 164893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 164993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 165000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 165100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 165200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 165300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 165400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 16554fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 165693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 165747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 165847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 165947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 166092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 166192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 166292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 166392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 166492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 166592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 166692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1667e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1668e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1669cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 167099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1671db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1672b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1673b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 167470982a5f95f68295244e5f6cc037c193713a5259Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 167570982a5f95f68295244e5f6cc037c193713a5259Dan Stoza new GraphicBufferAlloc()); 1676db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 16779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t hwcId = -1; 167899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 167902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 168002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 168102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 168299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1683db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 16848cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza if (mUseHwcVirtualDisplays) { 16858cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int width = 0; 16868cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int status = state.surface->query( 16878cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_WIDTH, &width); 16888cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16898cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query width (%d)", status); 16908cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int height = 0; 16918cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 16928cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_HEIGHT, &height); 16938cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16948cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query height (%d)", status); 16958cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int intFormat = 0; 16968cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 16978cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_FORMAT, &intFormat); 16988cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16998cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query format (%d)", status); 17008cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza auto format = static_cast<android_pixel_format_t>( 17018cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza intFormat); 17028cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 17038cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mHwc->allocateVirtualDisplay(width, height, &format, 17048cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza &hwcId); 17058cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 17069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 17075cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza // TODO: Plumb requested format back up to consumer 17085cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza 17099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VirtualDisplaySurface> vds = 17109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new VirtualDisplaySurface(*mHwc, 17119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId, state.surface, bqProducer, 17129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer, state.displayName); 1713db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1714db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 171547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 171699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 171799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1718cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1719cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1720cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1721cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 17229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (state.type == DisplayDevice::DISPLAY_EXTERNAL) { 17239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId = DisplayDevice::DISPLAY_EXTERNAL; 17249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface = new FramebufferSurface(*mHwc, 17259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_EXTERNAL, 17269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer); 17279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer = bqProducer; 17289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 17299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("Attempted to add non-external non-virtual" 17309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " display"); 17319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1732cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1733cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1734cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 173599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1736cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza state.type, hwcId, state.isSecure, display, 17389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface, producer, 173905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1740cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1741cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 17424fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 17438dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1744cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 17459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!state.isVirtualDisplay()) { 17467adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 17471c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 174893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 174992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 175092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 17558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 17568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 17578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 17588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 17608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 17618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 17638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 17648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 17658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 17678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 17688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 17708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 17718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 17728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 17738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 17758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 17762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool first = true; 17772047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 17788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 17798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 17808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 17811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 17822047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (first || currentlayerStack != layerStack) { 17838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 17848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 17858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 17868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 17878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 17888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 17898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 17908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 17918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 17928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 17938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 179491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 17958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 17968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 180091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 180191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 180291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 180391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 180491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 180591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 180691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 180791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 18088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 180991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 18102047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 18112047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr first = false; 18122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 18138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 18148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 18158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 18163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 18173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 18183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 18191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 18201eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 18213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 18223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 18233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 18243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 18253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 18263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 18273559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 18283559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 18293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 18302047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 18313559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 18323559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 18333559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 18343559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 18353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 18361eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 18373dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Region visibleReg = s.active.transform.transform( 18381501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 18391501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 18400aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 18412047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 1842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 184503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 184603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 184703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 184803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 184903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 185003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 18519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 18529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 18539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getHwcDisplayId() < 0) { 185403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 185503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 18569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 18579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 18589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->updateCursorPosition(displayDevice); 185903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 186003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 18624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 18634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 18644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 1865598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (!mLayersPendingRemoval.isEmpty()) { 18664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 18674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 1868e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordBufferingStats(mLayersPendingRemoval[i]->getName().string(), 1869e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mLayersPendingRemoval[i]->getOccupancyHistory(true)); 18704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 18714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 18724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 18734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 18744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 18754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 18764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 18774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 18784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 18794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 18802d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 18812d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 18824fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18852047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack, 188687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1888841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 18899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("computeVisibleRegions"); 1890841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 189587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18972047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInReverseZOrder([&](Layer* layer) { 1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 18991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 190101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 190287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 19032047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr return; 190487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1905ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1906ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1907ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1909ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1910ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1911ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1914ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1915ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1917ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1919ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1921ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1923ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1924a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1925a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1926a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1927a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1928a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1929a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1930a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1931a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1932a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1933a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1934ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1936da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 19374125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 19383dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Rect bounds(s.active.transform.transform(layer->computeBounds())); 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1940ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1941ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1942ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 19433dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const Transform tr(s.active.transform); 194422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza if (tr.preserveRects()) { 194522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transform the transparent region 194622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion = tr.transform(s.activeTransparentRegion); 19474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 194822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transformation too complex, can't do the 194922f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transparent region optimization. 195022f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion.clear(); 19514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1952ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1954ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 19553dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const int32_t layerOrientation = s.active.transform.getOrientation(); 19569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.alpha == 1.0f && !translucent && 1957ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1958ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1959ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 19784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1981a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1983ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1984ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1985ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1986ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1987ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1988ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1989ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1990ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1991ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1992a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1993ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 19944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 19954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1996ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1997ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 2000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 200287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2004ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 2005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 20068b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2007a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 2008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 2009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 2010a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 2011a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 20122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 201487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 2015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 201787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 201887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 201992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 20204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 20214297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 20224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 202392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 202492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 202587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 202687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 20276b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 2028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("handlePageFlip"); 20309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 2031d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson nsecs_t latchTime = systemTime(); 203299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 20334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 20346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 203551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 203651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 203751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 203851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 203951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 204051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 204151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 204251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 204351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 204451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 20452047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 20466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 20476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 20486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 20492047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mLayersWithQueuedFrames.push_back(layer); 2050ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2051ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 20526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 2053ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2054ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 20556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 20562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 20572047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 20589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 2059d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const Region dirty(layer->latchBuffer(visibleRegions, latchTime)); 2060ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 20611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 206287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 20634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 20644da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 20653b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 20666b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 20676b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 20686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 20696b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 20709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (frameQueued && mLayersWithQueuedFrames.empty()) { 20716b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 20726b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 20736b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 20746b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 20759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza return !mLayersWithQueuedFrames.empty(); 2076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2078ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 2079ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 20809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = true; 2081ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 2082ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 208399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2084830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition( 2085830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const sp<const DisplayDevice>& displayDevice, 208687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 2087edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20887143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 20897143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 20907143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 20917143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 2092830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0; 20937143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 20949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Skipping display composition"); 20957143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 20967143316af216fa92c31a60d4407b707637382da1Dan Stoza } 20977143316af216fa92c31a60d4407b707637382da1Dan Stoza 20989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doDisplayComposition"); 20999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 210087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 210187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2102b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 2103830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion.orSelf(dirtyRegion); 2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2105830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard uint32_t flags = displayDevice->getFlags(); 21060f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 210729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 210829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 210929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 2110830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->swapRegion.bounds()); 2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 21120f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 211329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 2114df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 211595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 21160f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 2117830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->swapRegion.bounds()); 2118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 211929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 2120830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard dirtyRegion.set(displayDevice->bounds()); 2121830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion = dirtyRegion; 2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2125830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard if (!doComposeSurfaces(displayDevice, dirtyRegion)) return; 2126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21279c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 2128830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapRegion.orSelf(dirtyRegion); 2129da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 2130da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 2131830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapBuffers(getHwComposer()); 2132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces( 21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<const DisplayDevice>& displayDevice, const Region& dirty) 2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposeSurfaces"); 21389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 21399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 21409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 21419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 oldColorMatrix; 21429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) && 21439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform); 21449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 21459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 21469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); 21479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 21489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool hasClientComposition = mHwc->hasClientComposition(hwcId); 21509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasClientComposition) { 21519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("hasClientComposition"); 2152a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 21539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) { 2154c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 21559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getDisplayName().string()); 21563f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 21573f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 21583f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 21593f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 21603f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 2161c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 2162a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2163a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 21649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId); 21659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasDeviceComposition) { 2166b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 2167b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 2168b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 21693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 2170b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 21719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->clearWithColor(0, 0, 0, 0); 2172b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 2173766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 21749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region bounds(displayDevice->getBounds()); 2175766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2176766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 2177766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 2178766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 21799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region letterbox(bounds.subtract(displayDevice->getScissor())); 2180766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2181766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 21829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Region region(displayDevice->undefinedRegion.merge(letterbox)); 2183766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2184766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 2185766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 2186766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2187b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 218887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 2189b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 21909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza drawWormhole(displayDevice, region); 2191b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 2192a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 2193f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 21949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 2195766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 2196f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 2197f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 21989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& bounds(displayDevice->getBounds()); 21999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& scissor(displayDevice->getScissor()); 2200f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 2201f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 2202f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 2203f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 22043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2205f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 22069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const uint32_t height = displayDevice->getHeight(); 22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->setScissor(scissor.left, height - scissor.bottom, 22083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 2209f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 2210f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 221185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 22124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 221385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 221485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 221585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 22164b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 22179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Rendering client layers"); 22189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& displayTransform = displayDevice->getTransform(); 22199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 222085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 22219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool firstLayer = true; 22229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 22239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region clip(dirty.intersect( 22249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 22259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Layer: %s", layer->getName().string()); 22269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Composition type: %s", 22279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza to_string(layer->getCompositionType(hwcId)).c_str()); 222885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 22299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza switch (layer->getCompositionType(hwcId)) { 22309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Cursor: 22319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Device: 22329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::SolidColor: { 2233ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 22349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getClearClientTarget(hwcId) && !firstLayer && 22359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->isOpaque(state) && (state.alpha == 1.0f) 22369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza && hasClientComposition) { 2237cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 2238cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 22391748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard layer->clearWithOpenGL(displayDevice); 2240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 224185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 224285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 22439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Client: { 22449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 224585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 2246a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 22479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza default: 2248da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 2249cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 22509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 22519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Skipping for empty clip"); 2252a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 22539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza firstLayer = false; 225485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 225585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 225685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 22579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 225885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 22599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 226085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 22619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 226285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 22634b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 22644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 2265f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 22669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 22679f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza getRenderEngine().setupColorTransform(oldColorMatrix); 22689f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 22699f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 2270f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 22719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->disableScissor(); 22723f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 2273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2275830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const { 2276830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const int32_t height = displayDevice->getHeight(); 22773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 22783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 2279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22817d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 2282ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 22836710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 228413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 22851b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 22867d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 22877d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 22887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 22897d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) { 22907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 22917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22927d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mCurrentState.layersSortedByZ.add(lbc); 22937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 22947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 229696f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 2297ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 22984f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 22997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 230096f0819f81293076e652792794a961543e6750d7Mathias Agopian} 230196f0819f81293076e652792794a961543e6750d7Mathias Agopian 230222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) { 230396f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 230422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza sp<Layer> layer = weakLayer.promote(); 230522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza if (layer == nullptr) { 230622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza // The layer has already been removed, carry on 230722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza return NO_ERROR; 230822851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza } 230922851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza 2310598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 2311598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (index >= 0) { 2312598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersPendingRemoval.push(layer); 2313598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersRemoved = true; 2314598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch setTransactionFlags(eTransactionNeeded); 2315598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return NO_ERROR; 2316598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch } 2317598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return status_t(index); 2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2320c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() { 2321dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 2322dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 2323dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 23243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 2326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 2329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 2330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 233199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 2334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23368b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 23378b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 23388b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 23398b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 23408b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 23417c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2342698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 234328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2344e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 23452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 23462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 23472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 23482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 23497c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 23502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 23512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 23527c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 23537c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 23547c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 23552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 23562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 23572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2361e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2362e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2363e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2364e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2365b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2366b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2367e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2368698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2369698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2370d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2371d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2372d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2373d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2374d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2375d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2376d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2377d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2378097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2379d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2380d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2381d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2382d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2383d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2384d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2385d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2386d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2387698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2388386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 23892a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // If a synchronous transaction is explicitly requested without any changes, 23902a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // force a transaction anyway. This can be used as a flush mechanism for 23912a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // previous async transactions. 23922a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr if (transactionFlags == 0 && (flags & eSynchronous)) { 23932a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr transactionFlags = eTransactionNeeded; 23942a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr } 23952a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr 239628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2397ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 2398ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags); 2399ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2400468051e20be19130572231266db306396a56402bIrvel 2401386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 240228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2403698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2404386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2405386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2406386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 24072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 24082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 24092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 24102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2411386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 24122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2413386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2414386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2415386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2416386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 24172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 24182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2419386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2420386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2421cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 24279a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 24289a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 24299a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 24309a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 24329a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 24333ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2434e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2436097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2439e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2440e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2441e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2444e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2445e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2446e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 244700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2448e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2449e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2458e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 246147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 246247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 246347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 246447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 246547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 246647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 246747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 246847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 246947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 247047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2471e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 248013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2481e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2482e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 248399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr bool geometryAppliesWithResize = 248499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr what & layer_state_t::eGeometryAppliesWithResize; 2485e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 248699e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) { 2487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 248882364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr } 2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 249347db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayer(s.z) && idx >= 0) { 2494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2496e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2505e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2506e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 25079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->setAlpha(s.alpha)) 2508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2518231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza if (what & layer_state_t::eFlagsChanged) { 2519e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2520e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2521e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2522e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 252399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setCrop(s.crop, !geometryAppliesWithResize)) 2524e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2525e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2526acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (what & layer_state_t::eFinalCropChanged) { 2527acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (layer->setFinalCrop(s.finalCrop)) 2528acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos flags |= eTraversalNeeded; 2529acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos } 2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 253347db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayerStack(s.layerStack) && idx >= 0) { 2534e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2535e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2536e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2537e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2538e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2539e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2540e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 25417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza if (what & layer_state_t::eDeferTransaction) { 25427dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza layer->deferTransactionUntil(s.handle, s.frameNumber); 25437dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // We don't trigger a traversal here because if no other state is 25447dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // changed, we don't want this to cause any more work 25457dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 2546c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr if (what & layer_state_t::eOverrideScalingModeChanged) { 2547c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr layer->setOverrideScalingMode(s.overrideScalingMode); 2548c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // We don't trigger a traversal here because if no other state is 2549c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // changed, we don't want this to cause any more work 2550c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr } 2551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2553e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2554e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 25554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 25560ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 25570ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 25584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 25594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25616e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2562921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 25636e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 25644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 25656e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 25668b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 25674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 25684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 25694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 25704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 25713165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 25723165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 25734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 25744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 25754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 25773165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 25784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 25794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 25804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 25814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 25824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 25834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25877d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 25887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 2589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25907d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 25917d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza result = addClientLayer(client, *handle, *gbp, layer); 25927d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 25937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 25947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 2595ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceCreation(layer); 25967d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 25977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 25984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 26024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 26034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 260692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 26128f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 26174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 26184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 26194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2620b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 26224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 26234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 26244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 26284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 26294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 26314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 26324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2633b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 26344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2635118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2636118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2637ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 26389a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 26396710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 26406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 26416710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 26426710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 2643ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceDeletion(l); 26446710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 26456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 26466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 26479a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 26489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 26499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 26509a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 265113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 26536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 26546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 265522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza return removeLayer(layer); 2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2658b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2659b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 266013a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 266101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 266213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 266313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 266413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 266501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 266601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2667692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 266801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 266913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 26704c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 26714c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 267247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 267347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 267413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 267513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 26776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 26789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 26799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 26806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 268113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 268213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 268313a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 268413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 268513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 268613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 2687c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 268813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 268913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 269013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 269113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 269213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 269313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 269413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 269513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 269613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 26972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 26982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 26992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 27002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 27012c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 27022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 270313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 27042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 27052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2706c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2707c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2708c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 27092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 27102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 27112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 27122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 27132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2714c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2715ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 2716ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel Mutex::Autolock _l(mStateLock); 2717ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken()); 2718ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (idx < 0) { 2719ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ALOGW("Surface Interceptor SavePowerMode: invalid display token"); 2720ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel return; 2721ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2722ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); 2723ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2724ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel 27252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 2726f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn on the display 27272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2728c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2729c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2730c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2731948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2732c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 2735b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 27362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 2737f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2738f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2739f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray param.sched_priority = 1; 2740f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { 2741f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_FIFO on display on"); 2742f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 27432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2744f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn off the display 2745f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2746f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { 2747f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_OTHER on display off"); 2748f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 2749f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2750c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2752948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2753cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2754cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2755cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2756c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 27572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 27582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 27592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 27602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 27612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2762b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2767db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2768db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 27692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2770b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 27712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 27722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 27732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2774b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 27752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2776db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 27772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 27787306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 27799e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 27802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 27812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2782db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 27832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2784db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2786b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2787b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 27882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2789db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2790b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2791b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2792b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2793b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 279799b49840d309727678b77403d6cc9f920111623fMathias Agopian 2798bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2799bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2800bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2801bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2802bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 280374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2804bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2806fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 28079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 28089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 2809fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 2810fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 28119795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 2812fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 2813fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 2814fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 28159795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 28169795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 281782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 281882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 281925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 282025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 282125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 282225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 282325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 282474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 282535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 282625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 282725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 282825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 282925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 283082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 283174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 283235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 283382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 283425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 283525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 283625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 283725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 283874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 283935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 284025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2841c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2842c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2843c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2844c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2845c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2846c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2847c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2848b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2849b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 2850b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 2851b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 2852b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2853b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 2854b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 285540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 285640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos if ((index < numArgs) && 2857d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson (args[index] == String16("--frame-events"))) { 285840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos index++; 2859d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson dumpFrameEventsLocked(result); 286040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos dumpAll = false; 286140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos } 2862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 28631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 286482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 286574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 286682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 286748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 286882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 286982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 287048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 287182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 287282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 287382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 287482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 287548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2876c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2877c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 287825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 28792047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 288074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 28812047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 288225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 288325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 288482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 288574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 288682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 288782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 288882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 288982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 289082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 289182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 289248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 28939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 28949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 289586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 28964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 28974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2898d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 28994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 29002047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 29014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2902d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 29034b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 29042047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 290582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 290682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2907ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 290825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2909c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 291025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 291125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 291225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 291325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 291425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 291525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 291625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 29172047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 291825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2919d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 292025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 29212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 29224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2923d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 292425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 292525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 29266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 29276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 29286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 29292047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 29306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 29312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 29326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 29336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 29346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 29356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 293663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const 29374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 293863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" [sf"); 29394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 294063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" HAS_CONTEXT_PRIORITY"); 29414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 29424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 294363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" NEVER_DEFAULT_TO_ASYNC_MODE"); 29444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 294563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard if (isLayerTripleBufferingDisabled()) 294663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" DISABLE_TRIPLE_BUFFERING"); 294763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append("]"); 29484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 29494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 2950b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 2951b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 2952b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 2953b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { 2954b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[b] / 1e9; 2955b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2956b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[b]) / mTotalTime; 2957b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 2958b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 2959b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 2960b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; 2961b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2962b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; 2963b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 2964b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza NUM_BUCKETS - 1, bucketTimeSec, percent); 2965b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 2966b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2967e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName, 2968e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>&& history) { 2969e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 2970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza auto& stats = mBufferingStats[layerName]; 2971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& segment : history) { 2972e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (!segment.usedThirdBuffer) { 2973e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.twoBufferTime += segment.totalTime; 2974e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2975e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (segment.occupancyAverage < 1.0f) { 2976e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime += segment.totalTime; 2977e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else if (segment.occupancyAverage < 2.0f) { 2978e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime += segment.totalTime; 2979e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2980e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++stats.numSegments; 2981e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime += segment.totalTime; 2982e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 2985d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) { 2986d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson result.appendFormat("Layer frame timestamps:\n"); 2987d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 2988d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 2989d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const size_t count = currentLayers.size(); 2990d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson for (size_t i=0 ; i<count ; i++) { 2991d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson currentLayers[i]->dumpFrameEvents(result); 2992d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson } 2993d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson} 2994d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 2995e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const { 2996e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("Buffering stats:\n"); 2997e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append(" [Layer name] <Active time> <Two buffer> " 2998e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza "<Double buffered> <Triple buffered>\n"); 2999e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 3000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza typedef std::tuple<std::string, float, float, float> BufferTuple; 3001e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::map<float, BufferTuple, std::greater<float>> sorted; 3002e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& statsPair : mBufferingStats) { 3003e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const char* name = statsPair.first.c_str(); 3004e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferingStats& stats = statsPair.second; 3005e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (stats.numSegments == 0) { 3006e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza continue; 3007e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3008e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = ns2ms(stats.totalTime) / 1000.0f; 3009e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float twoBufferRatio = static_cast<float>(stats.twoBufferTime) / 3010e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime; 3011e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float doubleBufferRatio = static_cast<float>( 3012e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime) / stats.totalTime; 3013e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float tripleBufferRatio = static_cast<float>( 3014e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime) / stats.totalTime; 3015e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza sorted.insert({activeTime, {name, twoBufferRatio, 3016e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza doubleBufferRatio, tripleBufferRatio}}); 3017e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3018e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& sortedPair : sorted) { 3019e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = sortedPair.first; 3020e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferTuple& values = sortedPair.second; 3021e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.appendFormat(" [%s] %.2f %.3f %.3f %.3f\n", 3022e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<0>(values).c_str(), activeTime, 3023e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<1>(values), std::get<2>(values), 3024e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<3>(values)); 3025e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3026e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("\n"); 3027e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 3028e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 3029e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 303074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 303174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 303282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 30333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 30343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 30353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 30363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 30373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 30383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 30393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 30403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 30413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 304282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 304382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 304482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 304582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 304682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 304782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 3048bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 304982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 30504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 30514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 30523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 30533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 30544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 30553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 30574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 30584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 30594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 30604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 30613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 3062ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 30633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 3064ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 3065ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 3066ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 30679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 30689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 306941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 307041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 307141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 307224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 307324cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 30749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, 30759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod()); 307641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 307741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 3078b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 3079b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3080b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 3081b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3082b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3083e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza dumpBufferingStats(result); 3084e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 30854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 308682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 308782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 308882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 308982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 30903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 309186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 30923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30932047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 30943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 30952047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 3096bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 309782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 30985f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 30995f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 31005f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 31013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 310286efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 31033e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 31055f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 310674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 31075f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 31085f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 31095f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 311082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 311182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 31121b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 31133e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 311474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 31153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31161b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 3117888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 31184297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 3119ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 31203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 31213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 31223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 31233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 3125ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 3126ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 3127875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 31289795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 31294297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 31302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 31312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 313274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 313382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 313482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 3135c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 313682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 313782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 3138ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 3139ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 3140ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 314182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 314282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 3143c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 31449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1e9 / activeConfig->getVsyncPeriod(), 31459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiX(), 31469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiY(), 3147ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 314882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 314974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 315082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 315182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 315274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 315382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 315482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 315582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 315682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 315782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 315874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 3159e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3160e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3161e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza /* 3162e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza * HWC layer minidump 3163e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza */ 3164e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t d = 0; d < mDisplays.size(); d++) { 3165e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 3166e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza int32_t hwcId = displayDevice->getHwcDisplayId(); 3167e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 3168e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza continue; 3169e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3170e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3171e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.appendFormat("Display %d HWC layers:\n", hwcId); 3172e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza Layer::miniDumpHeader(result); 3173e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t l = 0; l < count; l++) { 3174e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<Layer>& layer(currentLayers[l]); 3175e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza layer->miniDump(result, hwcId); 3176e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3177e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3178e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 317982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 318082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 318182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 318282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 31833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 318474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 31853e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza bool hwcDisabled = mDebugDisableHWC || mDebugRegion; 31879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza result.appendFormat(" h/w composer %s\n", 31889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcDisabled ? "disabled" : "enabled"); 318974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 319082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 319182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 319282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 319382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 319482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 319582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 3196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 319813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 319948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 3200db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 320148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 320248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 320348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 320448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 320548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 320648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 320748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 320848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 320948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 321048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 321148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 321248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 321348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 3214cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 3215cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 321663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 321763f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 321863f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 321963f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 322063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 322163f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 322263f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 322363f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 322463f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 322524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 322663f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 322763f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 322863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 322963f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 323063f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 323163f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 323263f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 323363f165fd6b86d04be94d4023e845e98560504a96Keun young Park 32346e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { 3235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 3236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 3237041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 3238698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 3239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 3240d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 3241d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 32422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 3243c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza case GET_HDR_CAPABILITIES: 3244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 3245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 3246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 3247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 3248a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 32493bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 325099b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 32516e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3252375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 3253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 32551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 32561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 32571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 32581b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 32591b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 32601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 32611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 326299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 326399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 32646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid); 32651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 32661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 32671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 3268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32706e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return OK; 32716e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard} 32726e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard 32736e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact( 32746e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 32756e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{ 32766e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard status_t credentialCheck = CheckTransactCodeCredentials(code); 32776e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard if (credentialCheck != OK) { 32786e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return credentialCheck; 32796e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard } 32801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 3283b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 328499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 3285375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3286375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 3287375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 3288e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 3289375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 3291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 3293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 329401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 329535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 3296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 3298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 3299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 330053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 330153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 330453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3305cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3306cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 3307cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 3308e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 3309e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 3310e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 3311e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 3312cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 33144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 33154d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 33164d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 33174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 331853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 331953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 332053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 332153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 332253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 332353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 3324a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 3325a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 3326a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 3327a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 3328a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 3329a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 3330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 333101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 3332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 3333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 3334b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 333512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 3336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 3338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 33394297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 33404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 3341ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 3342ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3343ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 3344ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 3345ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 3346ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 33479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 1: 33489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Protanomaly); 33499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 2: 33519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); 33529f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33539f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 3: 33549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Tritanomaly); 33559f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza default: 33579f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::None); 33589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 3359ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3360ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 33619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Correction); 3362ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 33639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Simulation); 3364ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3365ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 3366ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 33679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 33689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 33709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 33719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 33729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 33739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 33749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 33759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 3376794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 33779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza for (size_t j = 0; j < 4; j++) { 33789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mColorMatrix[i][j] = data.readFloat(); 33799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 33809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 33829c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 33839c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33849c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 33859c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 33869c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 3387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3388f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 3389f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 3390f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 3391645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 3392645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 3393f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 3394f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 3395ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 3396ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 3397ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 3398ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 3399ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 3400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 3401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 3406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3410468051e20be19130572231266db306396a56402bIrvel case 1020: { // Layer updates interceptor 3411468051e20be19130572231266db306396a56402bIrvel n = data.readInt32(); 3412468051e20be19130572231266db306396a56402bIrvel if (n) { 3413468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor enabled"); 3414ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays); 3415468051e20be19130572231266db306396a56402bIrvel } 3416468051e20be19130572231266db306396a56402bIrvel else{ 3417468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor disabled"); 3418468051e20be19130572231266db306396a56402bIrvel mInterceptor.disable(); 3419468051e20be19130572231266db306396a56402bIrvel } 3420468051e20be19130572231266db306396a56402bIrvel return NO_ERROR; 3421468051e20be19130572231266db306396a56402bIrvel } 34228cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza case 1021: { // Disable HWC virtual displays 34238cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza n = data.readInt32(); 34248cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !n; 34258cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza return NO_ERROR; 34268cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 3427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 3430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 343253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 343387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 343499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 343553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 343653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 343759119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 34382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 34392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 344059119e658a12279e8fff508f8773843de2d90917Mathias Agopian 34412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 34422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 34432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 3444b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 3445b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 3446b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 3447b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 34482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 34492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 3450b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 3451b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 3452b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 3453b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3454b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 3455b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 3456b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 3457b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 3458b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3459b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 3460b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 3461b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 3462b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 3463b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 34642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 34652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 34662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 34672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 34682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 3469b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 34702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 34712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 34722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 34732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 34752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 34762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 34772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 34782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3480b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 3481b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 3482b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 34832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 34842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 3485c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 34862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 34872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 34882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 34892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 3490b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 3491b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 3492b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 3493b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 34942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 34952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 34962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 3497b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 3498b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 3499b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 35002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 35012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 35022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 3503c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 35042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3507b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 35082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 35092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 35102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 3511b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 3512b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 3513b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 3514b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 3515097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 35162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 3517b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 35182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 3523c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 3524b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 3525b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 352653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos result(NO_ERROR), 3527b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 352853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos exitRequested(false), 352953390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos code(0), 353053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos data(NULL), 353153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos reply(NULL) 3532b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 3533b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 3534b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 35352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 35362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 35372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 35382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 35392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 35402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 3542b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 35432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 3544aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 35452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 3546b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 3547b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 3548b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 35492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 35502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 35522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 35552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3556c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3557ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 3558c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 35592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 35612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 35622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 35642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 35652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35665ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 35675ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 35685ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 3569b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder(); 35705ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 3571c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 3572c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 3573c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 3574c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 3575c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3576c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3577c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3578c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3579c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3580c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3581c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3582c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3583c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3584c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3585c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3586c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3587c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3588c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3589c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3590c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3591c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 35922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 35932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 35942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 35952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3596c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 35972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 35982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3599c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3600c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 36012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 3602b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot; 36032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3607c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3608ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 3609b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, 3610b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos Transform::orientation_flags rotation, 3611b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 36122a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3613c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 36142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3615c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3616b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos rotation(rotation), result(PERMISSION_DENIED), 3617b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos isLocalScreenshot(isLocalScreenshot) 36182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 36192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 36212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 36222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 36242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 36252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3626c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3627c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3628b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotation, isLocalScreenshot); 3629097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 36302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 36312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 36332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 36342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 36352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 36362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 36372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 36382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 36392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 36402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 36412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 36422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3643c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3644b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotationFlags, isLocalScreenshot); 36452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 36462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 36472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 36482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 36492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3651118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3652118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3653180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3654180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3655180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3656c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3657ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 3658c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3659180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3660180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 36613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3662180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3663180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 366489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 366589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 366689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 36670e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 3668180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3669c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3670c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3671c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3672c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3673c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3674c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3675c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3676c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3677c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3678c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3679c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3680be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3681be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3682c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3683c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3684c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3685c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3686be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3687be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3688c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3689c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3690180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 36913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3692180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3693180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3694c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3695c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 36963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3697180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3698180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 36993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3700180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 37012047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 37021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3703180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3704180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3705180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3706180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3707c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3708180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3709180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3710180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3711180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 37122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 3713180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3714931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3715180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3716180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3717180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 37182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 37192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 37202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3721c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3722ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr int32_t minLayerZ, int32_t maxLayerZ, 3723b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, Transform::orientation_flags rotation, 3724b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 372574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3726fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3727fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3728180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 37293502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_w = hw->getWidth(); 37303502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_h = hw->getHeight(); 37313502416204d9dbd905012ee586d8bd145323809fDan Stoza 37323502416204d9dbd905012ee586d8bd145323809fDan Stoza if (rotation & Transform::ROT_90) { 37333502416204d9dbd905012ee586d8bd145323809fDan Stoza std::swap(hw_w, hw_h); 37343502416204d9dbd905012ee586d8bd145323809fDan Stoza } 3735180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3736180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3737180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3738180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3739180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3740180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3741180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3742180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3743180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3744180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3745b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool secureLayerIsVisible = false; 37462047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 3747b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const Layer::State& state(layer->getDrawingState()); 3748b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ && 3749b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos state.z <= maxLayerZ && layer->isVisible() && 3750b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos layer->isSecure()) { 3751b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos secureLayerIsVisible = true; 3752b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 37532047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 3754b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 3755b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (!isLocalScreenshot && secureLayerIsVisible) { 3756b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos ALOGW("FB is protected: PERMISSION_DENIED"); 3757b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos return PERMISSION_DENIED; 3758b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3759b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 37600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 37610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 376283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 3763605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 3764605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Put the screenshot Surface into async mode so that 3765605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Layer::headFenceHasSignaled will always return true and we'll latch the 3766605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // first buffer regardless of whether or not its acquire fence has 3767605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // signaled. This is needed to avoid a race condition in the rotation 3768605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // animation. See b/30209608 3769605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos sur->setAsyncMode(true); 3770605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 37710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 377274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 37735a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 37745a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine if (result == NO_ERROR) { 37753ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 37763ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 37772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 37780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 37790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 37804ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 37810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 37820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 37832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 37840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 37850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 37860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 37870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 37880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 37890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 37900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3791866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 37920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 37930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 37940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 37950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 37960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 37973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 37983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 37993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 38003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 38010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 38020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 38030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 38040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3805c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3806c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3807c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3808d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3809866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3810866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3811866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3812866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3813866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3814866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 38159707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 38169707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3817866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3818866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3819866399093f9f60e7305f291e688abb456bace710Riley Andrews } 38202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3821866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3822866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3823866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3824866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3825866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3826866399093f9f60e7305f291e688abb456bace710Riley Andrews } 38272d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3828866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3829866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3830866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3831866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3832866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3833866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3834866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3835866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3836866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3837866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3838866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3839866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3840866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3841866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 38422d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3843866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 38442d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 38452d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3846d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3847d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3848d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3849d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3850d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3851d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3852d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3853d555684cb36dfb959694db76962e570184f98838Mathias Agopian 38540aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38550aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 38560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 3857f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu window->cancelBuffer(window, buffer, syncFd); 3858f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu buffer = NULL; 38590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 38600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 38610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 38620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 386474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3865f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu if (buffer) { 3866f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu // queueBuffer takes ownership of syncFd 3867f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu result = window->queueBuffer(window, buffer, syncFd); 3868f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu } 386974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 38700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 387274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 38730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 387474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 387574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 387674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 387774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 387874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3879d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3880ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) { 3881fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3882d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3883d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3884d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3885fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3886fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3887fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3888fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3889fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3890fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 38912047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr size_t i = 0; 38922047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 3893fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3894fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3895fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3896fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 38979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", 3898fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 38992047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr i, layer->getName().string(), state.layerStack, state.z, 3900fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 39012047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr i++; 39022047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 3903fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3904ce796e78a57018f186b062199c75d94545318acaPablo Ceballos} 3905ce796e78a57018f186b062199c75d94545318acaPablo Ceballos 39061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 39071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 39082047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const { 39092047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layersSortedByZ.traverseInZOrder(consume); 3910921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3911921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 39122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const { 39132047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layersSortedByZ.traverseInReverseZOrder(consume); 3914921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3915921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 39173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 39203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 39213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 39223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 39243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 39253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3926