SurfaceFlinger.cpp revision 6e8e98a23592c2522396b673145814a4bbee69db
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/log.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.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 9422819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// Workaround for b/30067360: /proc/self/environ inaccessible in SurfaceFlinger 9522819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// => ASan fails to read ASAN_OPTIONS => alloc-dealloc-mismatch bug is not 9622819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// suppressed and prevents the device from booting. 9722819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#ifndef __has_feature 9822819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#define __has_feature(x) 0 9922819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#endif 10022819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#if __has_feature(address_sanitizer) 10122819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov__attribute__((visibility("default"))) 10222819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanovextern "C" const char* __asan_default_options() { 10322819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov return "alloc_dealloc_mismatch=0"; 10422819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov} 10522819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#endif 10622819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 119faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 120faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 121faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 122faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 123faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 124faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 125faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 126faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 127faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 128faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 129faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 130faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1320a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 13799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 13899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 13999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 14099b49840d309727678b77403d6cc9f920111623fMathias Agopian 14199b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 14299b49840d309727678b77403d6cc9f920111623fMathias Agopian 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1444f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 148076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 14952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 150875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 1529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mBuiltinDisplays(), 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 1549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid(false), 1554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1578afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 15873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 159a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 164ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 165ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 166468051e20be19130572231266db306396a56402bIrvel mInterceptor(), 1674a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mPrimaryDispSync("PrimaryDispSync"), 168faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 169948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 170b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasColorMatrix(false), 171b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff(false), 172b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets(), 173b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime(0), 174b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime(0) 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 176a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1808afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 181b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 18250210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 183b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1868afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1878afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1888afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 19063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 19163f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 19263f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 19363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 195c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 196c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 197c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza 198c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza property_get("debug.sf.disable_backpressure", value, "0"); 199c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza mPropagateBackpressure = !atoi(value); 200c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation"); 2018cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 2028cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza property_get("debug.sf.disable_hwc_vds", value, "0"); 2038cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !atoi(value); 2048cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays"); 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 20899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 20999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 21099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 219c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 22099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 22199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 22299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 22313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 22413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 22599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 22699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 227a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 22899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 22999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2307e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 23296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 23396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 23496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 23596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 23696f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 241dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 242dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 253c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit DisplayToken(const sp<SurfaceFlinger>& flinger) 254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 260e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 26153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure); 2628dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 263e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 264ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayCreation(info); 265e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2736c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2766c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2786c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2796c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2806c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2816c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 282ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayDeletion(info.displayId); 2836c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2846c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2856c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2866c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 2889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("createBuiltinDisplayLocked(%d)", type); 289692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 290692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 291692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 292692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 29353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(type, true); 294692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 295ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveDisplayCreation(info); 296692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 297692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2999e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 300e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 301e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 302e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 303692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 304e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 305e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 3069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 3079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 3089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 3099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 3109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 316a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 3173330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 3181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3191f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 3201f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 3211f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 3221f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 323921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 3241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 3251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 327a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 328a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 329a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 3300a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato 3310a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato const int LOGTAG_SF_STOP_BOOTANIM = 60110; 3320a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, 3330a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 340921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 343921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 344921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 346921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 347921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 348921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 350921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 351921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3554a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* name) : 3564a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mName(name), 3570a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3580a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3594a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncOnLabel(String8::format("VsyncOn-%s", name)), 3604a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncEventLabel(String8::format("VSYNC-%s", name)), 361db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mDispSync(dispSync), 362db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallbackMutex(), 363db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallback(), 364db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mVsyncMutex(), 365db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset(phaseOffset), 366db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled(false) {} 367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 371db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3734a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray status_t err = mDispSync->addEventListener(mName, mPhaseOffset, 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 380faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3875167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 388faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled = enable; 390faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 391faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 392faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 394faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 395faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 396faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza virtual void setPhaseOffset(nsecs_t phaseOffset) { 398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Normalize phaseOffset to [0, period) 401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza auto period = mDispSync->getPeriod(); 402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset %= period; 403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (phaseOffset < 0) { 404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're here, then phaseOffset is in (-period, 0). After this 405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // operation, it will be in (0, period) 406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset += period; 407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset = phaseOffset; 409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're not enabled, we don't need to mess with the listeners 411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (!mEnabled) { 412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return; 413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Remove the listener with the old offset 416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza status_t err = mDispSync->removeEventListener( 417db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 418db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 419db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error unregistering vsync callback: %s (%d)", 420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 421db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 422db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 423db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Add a listener with the new offset 4244a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray err = mDispSync->addEventListener(mName, mPhaseOffset, 425db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 426db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 427db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error registering vsync callback: %s (%d)", 428db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 429db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 430db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 431db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4390a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 4400a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 4415167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 4420a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 443faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 444faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 445faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 446faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 448faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 449faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4504a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* const mName; 4514a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 453faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4540a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 4555167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 4565167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 4570a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 460db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mCallbackMutex; // Protects the following 461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 462db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 463db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mVsyncMutex; // Protects the following 464db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza nsecs_t mPhaseOffset; 465db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza bool mEnabled; 466faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 467faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 468c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource { 469c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic: 470c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju InjectVSyncSource() {} 471c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 472c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual ~InjectVSyncSource() {} 473c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 474c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 475c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 476c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mCallback = callback; 477c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 478c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 479c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void onInjectSyncEvent(nsecs_t when) { 480c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 481c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mCallback->onVSyncEvent(when); 482c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 483c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 484c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setVSyncEnabled(bool) {} 485c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju virtual void setPhaseOffset(nsecs_t) {} 486c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 487c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate: 488c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::mutex mCallbackMutex; // Protects the following 489c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju sp<VSyncSource::Callback> mCallback; 490c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}; 491c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 492faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 495a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza { // Autolock scope 4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize EGL for the default display 5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza eglInitialize(mEGLDisplay, NULL, NULL); 502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // start the EventThread 5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, true, "app"); 506ab04685578b254c2eaf43bf5da85e5e922787825Irvel mEventThread = new EventThread(vsyncSrc, *this, false); 5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sfVsyncPhaseOffsetNs, true, "sf"); 509ab04685578b254c2eaf43bf5da85e5e922787825Irvel mSFEventThread = new EventThread(sfVsyncSrc, *this, true); 5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mEventQueue.setEventThread(mSFEventThread); 511a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 512acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray // set SFEventThread to SCHED_FIFO to minimize jitter 51341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray struct sched_param param = {0}; 51435520634e298f53bd8433825640d6999760f25b3Tim Murray param.sched_priority = 2; 51541a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) { 51641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray ALOGE("Couldn't set SCHED_FIFO for SFEventThread"); 51741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray } 51841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray 5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Get a RenderEngine for the given display / config (can't fail) 5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine = RenderEngine::create(mEGLDisplay, 5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza HAL_PIXEL_FORMAT_RGBA_8888); 5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 523f9481058101c4e2b38c74048feac383664691d03Saurabh Shah 5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Drop the state lock while we initialize the hardware composer. We drop 5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // the lock because on creation, it will call back into SurfaceFlinger to 5269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // initialize the primary display. 5279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc = new HWComposer(this); 5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this)); 529b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock _l(mStateLock); 531875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 532875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 533875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 534a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 535da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 536da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 537da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // make the GLContext current so that we can create textures when creating 5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Layers (which may happens before we render something) 540a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 541a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 542d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 543d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 544d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 54592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 54692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 5478630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 54813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 54913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 55013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 5514e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza mRenderEngine->primeCache(); 5524e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza 553a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 554a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Done initializing"); 5573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 5583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 559a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 560a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 561a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 562a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 563a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 564a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 565875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 566875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 567a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 568a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 569875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 570875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 571a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 572a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 574d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 575582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 5762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 577134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 578097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 5796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 580134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 581134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 58423e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa if ((configs == NULL) || (display.get() == NULL)) { 5857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5887aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 5897aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 5907aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 591692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5929e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 593692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5941604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5951604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5961604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5971604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5981604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5991604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 6001604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 601c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 6048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 6058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 6068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 6078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 6088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 6098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 6108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 6128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 6148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 6158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 6168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 6178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 6188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 6191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 6207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 6217f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (const auto& hwConfig : getHwComposer().getConfigs(type)) { 6237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 6247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float xdpi = hwConfig->getDpiX(); 6269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float ydpi = hwConfig->getDpiY(); 6277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 6307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 6337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 6347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 6407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 6417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 6457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 6467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 6477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 6487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 6517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 6521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.w = hwConfig->getWidth(); 6559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.h = hwConfig->getHeight(); 6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 6577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 6589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.fps = 1e9 / hwConfig->getVsyncPeriod(); 65991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 66191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 66291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 66391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 66491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 66591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 66691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 66791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 66891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 66991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 67091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 67191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 67291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.presentationDeadline = hwConfig->getVsyncPeriod() - 6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 6757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 6777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 67928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright configs->push_back(info); 6808b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6818b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 684dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 68589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 68667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 68767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 68867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 68967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 69067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 69167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 69267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 69367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 69467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 69567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 69667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 69767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 6986c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 69924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza sp<DisplayDevice> device(getDisplayDevice(display)); 70024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 70124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 70224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 70324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 7047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 705dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 7136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 7146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 7156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 7186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 7346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 7356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 7367306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 7377306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 738784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 7399ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 7407306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 74128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 7427306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 7436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 7446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 7456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 7467306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 7476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 7486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 7496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 7506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 7516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 7526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 7546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 7566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 7576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 758888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 759c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 76028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display, 76128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t>* outColorModes) { 76228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if ((outColorModes == nullptr) || (display.get() == nullptr)) { 76328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return BAD_VALUE; 76428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 76528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 76628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (!display.get()) { 76728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NAME_NOT_FOUND; 76828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 76928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = NAME_NOT_FOUND; 77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (display == mBuiltinDisplays[i]) { 77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright type = i; 77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright break; 77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type < 0) { 77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return type; 78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type); 78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright outColorModes->clear(); 78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); 78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) { 79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> device(getDisplayDevice(display)); 79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (device != nullptr) { 79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return device->getActiveColorMode(); 79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return static_cast<android_color_mode_t>(BAD_VALUE); 79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw, 79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) { 79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright this); 80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = hw->getDisplayType(); 80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t currentMode = hw->getActiveColorMode(); 80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mode == currentMode) { 80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode); 80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Trying to set config for virtual display"); 81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return; 81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright hw->setActiveColorMode(mode); 81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright getHwComposer().setActiveColorMode(type, mode); 81628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 81728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 81828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 81928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display, 82028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t colorMode) { 82128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright class MessageSetActiveColorMode: public MessageBase { 82228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright SurfaceFlinger& mFlinger; 82328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<IBinder> mDisplay; 82428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mMode; 82528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright public: 82628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp, 82728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright android_color_mode_t mode) : 82828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger(flinger), mDisplay(disp) { mMode = mode; } 82928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright virtual bool handler() { 83028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright Vector<android_color_mode_t> modes; 83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.getDisplayColorModes(mDisplay, &modes); 83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes); 83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (mMode < 0 || !exists) { 83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode, 83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mDisplay.get()); 83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (hw == nullptr) { 84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGE("Attempt to set active color mode = %d for null display %p", 84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode, mDisplay.get()); 84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright ALOGW("Attempt to set active color mode= %d for virtual display", 84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mMode); 84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else { 84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.setActiveColorModeInternal(hw, mMode); 84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright }; 85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode); 85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright postMessageSync(msg); 85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 855c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 856d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 857d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 858d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 859d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 860d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 861d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 862d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 863d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 864d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 865d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 866d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 867d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 868c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, 869c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza HdrCapabilities* outCapabilities) const { 870c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza Mutex::Autolock _l(mStateLock); 871c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 872c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza sp<const DisplayDevice> displayDevice(getDisplayDevice(display)); 873c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (displayDevice == nullptr) { 874c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get()); 875c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 876c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 877c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 878c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::unique_ptr<HdrCapabilities> capabilities = 879c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); 880c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (capabilities) { 881c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza std::swap(*outCapabilities, *capabilities); 882c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } else { 883c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 884c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 885c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 886c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return NO_ERROR; 887c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza} 888c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 889c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) { 890c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable == mInjectVSyncs) { 891c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 892c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 893c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 894c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (enable) { 895c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 896c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections enabled"); 897c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mVSyncInjector.get() == nullptr) { 898c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector = new InjectVSyncSource(); 899ab04685578b254c2eaf43bf5da85e5e922787825Irvel mInjectorEventThread = new EventThread(mVSyncInjector, *this, false); 900c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 901c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mInjectorEventThread); 902c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } else { 903c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 904c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("VSync Injections disabled"); 905c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mEventQueue.setEventThread(mSFEventThread); 906c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector.clear(); 907c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 908c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 909c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 910c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 911c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) { 912c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (!mInjectVSyncs) { 913c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGE("VSync Injections not enabled"); 914c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return BAD_VALUE; 915c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 916c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) { 917c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("Injecting VSync inside SurfaceFlinger"); 918c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector->onInjectSyncEvent(when); 919c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 920c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 921c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 922c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 923d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 924d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 925d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 9268aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 927bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 928bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 93099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 93199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 93299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 93399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 93499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 93599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 93699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 93799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 93899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 93999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 94099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 94199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 94299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 94399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 94499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 94599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 95299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 953c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 95699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 95799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 95899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 95999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9614f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 9624f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 9634f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 9644f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 96599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 967faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 968faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 969948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 970faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 971d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 972d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 973faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 97443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 975faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 976faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 977948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 978faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 979faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 980948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 981948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 982948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 9830a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // Hardware vsync is not currently available, so abort the resync 9840a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // attempt for now 985948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 986948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 987948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 9889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 9899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 990faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 991faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 992faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 993faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 994faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 995faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 996d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 997d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 998faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 999faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1000faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1001faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1002948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 1005d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 1006d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 1008faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 1009faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1010948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 1011948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 1012948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1014faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 10154a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() { 10164a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray static constexpr nsecs_t kIgnoreDelay = ms2ns(500); 10174a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray if (systemTime() - mLastSwapTime > kIgnoreDelay) { 10180a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza resyncToHardwareVsync(false); 10194a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray } 10204a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray} 10214a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 10229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) { 1023d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 1024faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1025d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 1026d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1027d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 1028d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 1029faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1030148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 1031d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 1032d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 1033d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 1034d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 1035d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 1036d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 1037148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 1038148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 10399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) { 10409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false"); 10419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (disp == DisplayDevice::DISPLAY_PRIMARY) { 10429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Mutex::Autolock lock(mStateLock); 10439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // All non-virtual displays are currently considered secure. 10459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool isSecure = true; 10469e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 10479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t type = DisplayDevice::DISPLAY_PRIMARY; 10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY); 10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza wp<IBinder> token = mBuiltinDisplays[type]; 10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferProducer> producer; 10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<IGraphicBufferConsumer> consumer; 10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new GraphicBufferAlloc()); 10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, 10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, consumer); 10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<DisplayDevice> hw = new DisplayDevice(this, 10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs, 10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer, mRenderEngine->getEGLConfig()); 10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mDisplays.add(token, hw); 10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto type = DisplayDevice::DISPLAY_EXTERNAL; 10649e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 1065692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza createBuiltinDisplayLocked(type); 10679e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 1068692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 1069692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 10709e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 10719e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 10729e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 10739e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 10743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 10758630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10768630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) { 1078faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza getHwComposer().setVsyncEnabled(disp, 10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); 10818630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 10828630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 10834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 10841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 108599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 10866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 10875018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza bool frameMissed = !mHadClientComposition && 10885018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence != Fence::NO_FENCE && 10895018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence->getSignalTime() == INT64_MAX; 10905018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); 1091c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza if (mPropagateBackpressure && frameMissed) { 10925018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza signalLayerUpdate(); 10935018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza break; 10945018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza } 10955018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza 10966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 10976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 10985878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 10996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 11005878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 11015878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 11025878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 11036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 11046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 11066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 11106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 11114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11146b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 1115e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 11164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 111787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 11186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 11194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 11206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 11214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11236b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 11256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 11264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 11273a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 1129cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 113014cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 113140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 113205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 113305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza preComposition(); 113405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza rebuildLayerStacks(); 113505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza setUpHWComposer(); 113605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doDebugFlashRegions(); 113705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doComposition(); 113805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza postComposition(refreshStartTime); 113905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 114005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY); 1141bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza 1142bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = false; 1143bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1144bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1145bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = mHadClientComposition || 1146bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); 1147bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza } 114814cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 11499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Release any buffers which were replaced this frame 11509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 11519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->releasePendingBuffer(); 11529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 11539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.clear(); 1154cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1155cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1156cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 1157cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 1158cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 1159cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 1160cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 1161cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1162cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 1163cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1164cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 11652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1166cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1167cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 1169cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 1170cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 1171cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1172cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 1173cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 11743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 11753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 11763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1177da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1178cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1179cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1180cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1181cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1182cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 1183cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1184cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 1185cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1187bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 11889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 11897bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 11907bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 11917bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 11927bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 11937bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 11947bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 11959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 11969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 1197bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 1198cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1199cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1200cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 1201cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 12029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("preComposition"); 12049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1205cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 12061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 12071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1208cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 12091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 1210cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 1211cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 1215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 121840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime) 1219cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 12209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postComposition"); 12229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 12231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 12241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1225cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 1226e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza bool frameLatched = layers[i]->onPostComposition(); 1227e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (frameLatched) { 1228e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordBufferingStats(layers[i]->getName().string(), 1229e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza layers[i]->getOccupancyHistory(false)); 1230e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 1231cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 12324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> presentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY); 1234faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1235faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 1236faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 1237faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1238faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1239948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1240faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1241faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1242faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1243b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 12445167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 12452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1246faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1247faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1248faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1249faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 125040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos mFenceTracker.addFrame(refreshStartTime, presentFence, 125140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence()); 125240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 12534b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 12544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 12554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 1256a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 12574b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 12584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 12594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 12604b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 12619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nsecs_t presentTime = 12629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 12634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 12644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 12654b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 12664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1267b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1268b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1269b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1270b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1271b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1272b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1273b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1274b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1275b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1276b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t period = mPrimaryDispSync.getPeriod(); 1277b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t elapsedTime = currentTime - mLastSwapTime; 1278b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza size_t numPeriods = static_cast<size_t>(elapsedTime / period); 1279b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (numPeriods < NUM_BUCKETS - 1) { 1280b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[numPeriods] += elapsedTime; 1281b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1282b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; 1283b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1284b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime += elapsedTime; 1285b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1286b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime = currentTime; 1287cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1288cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1289cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 12909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 12919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("rebuildLayerStacks"); 12929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1293cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 129452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1295cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 129687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 129787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 1298ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 12991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 130092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1301ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 1302ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 13039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Vector<sp<Layer>> layersSortedByZ; 13049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<DisplayDevice>& displayDevice(mDisplays[dpy]); 13059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& tr(displayDevice->getTransform()); 13069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect bounds(displayDevice->getBounds()); 13079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->isDisplayOn()) { 13081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 13099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getLayerStack(), dirtyRegion, 13109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza opaqueRegion); 13117e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 13121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1313ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 13141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 13151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 13169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.layerStack == displayDevice->getLayerStack()) { 1317a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 1318a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 1319a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 1320a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 1321ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 13229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Clear out the HWC layer if this layer was 13249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // previously visible, but no longer is 13259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(displayDevice->getHwcDisplayId(), 13269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nullptr); 1327ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 132887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 132987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 13303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 13319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); 13329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.set(bounds); 13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->undefinedRegion.subtractSelf( 13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza tr.transform(opaqueRegion)); 13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->dirtyRegion.orSelf(dirtyRegion); 13363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 13373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1338cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 13393b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1340cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 13419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 13429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("setUpHWComposer"); 13439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1344028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1345b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1346b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1347b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1348b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1349b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1350b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1351b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1352b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1353b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1354b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1355b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1356b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1357b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1358b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1359b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1360b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1361b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1362b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1363b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1364b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1365b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 13667143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1367b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1368b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1369b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1370b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1371028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1372028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 13739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // build the h/w work list 13749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (CC_UNLIKELY(mGeometryInvalid)) { 13759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = false; 13769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 13779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<const DisplayDevice> displayDevice(mDisplays[dpy]); 13789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 13799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 13809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Vector<sp<Layer>>& currentLayers( 13819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getVisibleLayersSortedByZ()); 13829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool foundLayerWithoutHwc = false; 13839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : currentLayers) { 13849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!layer->hasHwcLayer(hwcId)) { 13859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = mHwc->createLayer(hwcId); 13869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcLayer) { 13879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setHwcLayer(hwcId, std::move(hwcLayer)); 13889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 13899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 13909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza foundLayerWithoutHwc = true; 13919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 1392a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1393a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1394a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 13959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setGeometry(displayDevice); 13969f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (mDebugDisableHWC || mDebugRegion) { 13979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 139803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 139903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 140003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 140103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 140303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 14049f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14059f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 14069f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Set the per-frame data 14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId < 0) { 14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14149f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (colorMatrix != mPreviousColorMatrix) { 14159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza status_t result = mHwc->setColorTransform(hwcId, colorMatrix); 14169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " 14179f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza "display %zd: %d", displayId, result); 14189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setPerFrameData(displayDevice); 142138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 142252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 14239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 14249f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mPreviousColorMatrix = colorMatrix; 14259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 14269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14277bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 14287bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 14297bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 14307bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 14317bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 14327bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza status_t result = displayDevice->prepareFrame(*mHwc); 14339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 14349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 14359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1436cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 143752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1438cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1439cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 14409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposition"); 14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 144252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 144392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 14452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1446cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1447cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 144802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 144902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 145002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 145102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1452cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1453cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1454cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 145587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 145752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1462841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 14639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postFramebuffer"); 1464b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1465a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1466a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1467c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 14689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 14699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 14707bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 14717bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 14727bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 14739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 14749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 14759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->commit(hwcId); 14769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14772dc3be88bd85791556ab0e6df6a080989886749eDan Stoza displayDevice->onSwapBuffersCompleted(); 1478b2c838b7add20c4515966a80de809b0a1d315001Season Li displayDevice->makeCurrent(mEGLDisplay, mEGLContext); 14799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 14809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<Fence> releaseFence = Fence::NO_FENCE; 14819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) { 14829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = displayDevice->getClientTargetAcquireFence(); 14839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 14849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto hwcLayer = layer->getHwcLayer(hwcId); 14859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer); 148652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 14879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->onLayerDisplayed(releaseFence); 14889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 14899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 14909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mHwc->clearReleaseFences(hwcId); 1491ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1492e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1493e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 14966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 14976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 14986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 14996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 15006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 150387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1505841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1506841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 15077cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 15087cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 15097cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 15107cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 15117cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 15127cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 152487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 15303d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 153287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 15333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 15343d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // Notify all layers of available frames 15387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza for (size_t i = 0; i < count; ++i) { 15397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza currentLayers[i]->notifyAvailableFrames(); 15407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 15417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 154913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 15603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 156492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 156592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 156692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 156992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 157192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 157293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 157392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 157492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 157592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 157692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 157792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 157892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 158192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 15823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 158327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 158427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 158527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 158602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1587875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 158802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 158902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 159002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 15919e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 15927adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 159302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 159492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 159592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 159692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 159792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 159892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 16003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1601097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1602097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 16031474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 160593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 160693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 160793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 160802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 160902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 161002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 161193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 161293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 161393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 161493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 161593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 161692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 161793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1618db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 161993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 162093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 162193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 162293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 162300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 162400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 162500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 162600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 162700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 16284fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 162993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 163047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 163147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 163247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 163392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 163492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 163592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 163692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 163792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 163892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 163992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1640e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1641e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1642cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 164399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1644db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1645b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1646b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 164770982a5f95f68295244e5f6cc037c193713a5259Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 164870982a5f95f68295244e5f6cc037c193713a5259Dan Stoza new GraphicBufferAlloc()); 1649db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 16509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza int32_t hwcId = -1; 165199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 165202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 165302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 165402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 165599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1656db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 16578cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza if (mUseHwcVirtualDisplays) { 16588cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int width = 0; 16598cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int status = state.surface->query( 16608cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_WIDTH, &width); 16618cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16628cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query width (%d)", status); 16638cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int height = 0; 16648cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 16658cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_HEIGHT, &height); 16668cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16678cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query height (%d)", status); 16688cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza int intFormat = 0; 16698cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza status = state.surface->query( 16708cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza NATIVE_WINDOW_FORMAT, &intFormat); 16718cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza ALOGE_IF(status != NO_ERROR, 16728cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza "Unable to query format (%d)", status); 16738cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza auto format = static_cast<android_pixel_format_t>( 16748cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza intFormat); 16758cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 16768cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mHwc->allocateVirtualDisplay(width, height, &format, 16778cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza &hwcId); 16788cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 16799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 16805cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza // TODO: Plumb requested format back up to consumer 16815cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza 16829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<VirtualDisplaySurface> vds = 16839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza new VirtualDisplaySurface(*mHwc, 16849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId, state.surface, bqProducer, 16859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer, state.displayName); 1686db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1687db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 168847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 168999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 169099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1691cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1692cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1693cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1694cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 16959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (state.type == DisplayDevice::DISPLAY_EXTERNAL) { 16969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcId = DisplayDevice::DISPLAY_EXTERNAL; 16979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface = new FramebufferSurface(*mHwc, 16989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza DisplayDevice::DISPLAY_EXTERNAL, 16999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bqConsumer); 17009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza producer = bqProducer; 17019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 17029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("Attempted to add non-external non-virtual" 17039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " display"); 17049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 1705cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1706cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1707cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 170899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1709cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 17109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza state.type, hwcId, state.isSecure, display, 17119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza dispSurface, producer, 171205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1713cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1714cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 17154fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 17168dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1717cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 17189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!state.isVirtualDisplay()) { 17197adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 17201c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 172193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 172292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 172392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 17288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 17298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 17308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 17318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 17338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 17348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 17368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 17378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 17388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 17408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 17418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 17438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 17448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 17458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 17468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 17478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 17488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 17498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 17508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 17518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 17528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 175313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 17541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 17558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 17568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 17578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 17588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 17598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 17608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 17618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 17628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 17638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 17648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 17658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 17668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 176791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 17688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 17698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 177391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 177491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 177591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 177691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 177791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 177891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 177991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 178091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 17818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 178291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 17838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 17858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 17868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 17873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 17883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 17893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 17921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 17933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 17943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 17953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 17963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 17973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 17983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 17993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 18003559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 18013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 18021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 18033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 18041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 18053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 18063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 18073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 18083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 18093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 18101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 18113dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Region visibleReg = s.active.transform.transform( 18121501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 18131501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 18140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 181903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 182003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 182103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 182203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 182303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 182403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 18259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 18269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 18279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getHwcDisplayId() < 0) { 182803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 182903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 18309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 18319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 18329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->updateCursorPosition(displayDevice); 183303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 183403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 18354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 18364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 18374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 18384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 1839598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (!mLayersPendingRemoval.isEmpty()) { 18404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 18414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 1842e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza recordBufferingStats(mLayersPendingRemoval[i]->getName().string(), 1843e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza mLayersPendingRemoval[i]->getOccupancyHistory(true)); 18444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 18454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 18464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 18474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 18484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 18494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 18504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 18514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 18524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 18534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 18542d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 18552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 18564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 186087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 186187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 18649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("computeVisibleRegions"); 1865841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 187413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 18771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 188087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 188187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 188287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1883ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1884ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1885ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1887ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1888ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1902a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1903a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1904a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1905a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1906a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1907a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1908a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1909a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1910a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1911a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1914da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 19154125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 19163dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr Rect bounds(s.active.transform.transform(layer->computeBounds())); 1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1919ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 19213dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const Transform tr(s.active.transform); 192222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza if (tr.preserveRects()) { 192322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transform the transparent region 192422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion = tr.transform(s.activeTransparentRegion); 19254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 192622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transformation too complex, can't do the 192722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transparent region optimization. 192822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion.clear(); 19294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1930ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 19333dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr const int32_t layerOrientation = s.active.transform.getOrientation(); 19349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (s.alpha == 1.0f && !translucent && 1935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1938ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1942ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1943ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1944ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 19564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1959a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1963ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1970a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 19724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1974ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1975ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 198087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 19848b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1985a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1988a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1989a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 199287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 199587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 199687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 199792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 19984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 19994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 20004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 200192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 200292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 200387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 200487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 20056b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 2006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("handlePageFlip"); 20089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 20094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 201099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 20114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 20121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 20136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 201451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 201551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 201651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 201751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 201851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 201951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 202051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 202151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 202251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 202351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 202451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layers.size(); i<count ; i++) { 20251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 20266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 20276b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 20286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 20299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.push_back(layer.get()); 2030ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2031ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 20326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 2033ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2034ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 20356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 203651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner } 20379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 203887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 2039ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 20401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 204187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 20424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 20434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 20443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 20456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 20466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 20476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 20486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 20499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (frameQueued && mLayersWithQueuedFrames.empty()) { 20506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 20516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 20526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 20536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 20549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza return !mLayersWithQueuedFrames.empty(); 2055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2057ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 2058ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = true; 2060ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 2061ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 206299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2063cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 206487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 2065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20667143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 20677143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 20687143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 20697143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 20707143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 20717143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 20729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Skipping display composition"); 20737143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 20747143316af216fa92c31a60d4407b707637382da1Dan Stoza } 20757143316af216fa92c31a60d4407b707637382da1Dan Stoza 20769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doDisplayComposition"); 20779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 207887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 207987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2080b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 20814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 2082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 20840f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 208529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 208629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 208729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 20884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 20900f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 209129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 2092df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 209395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 20940f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 20954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 2096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 209729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 20984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 20994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 2100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (!doComposeSurfaces(hw, dirtyRegion)) return; 2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 21064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 2107da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 2108da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 2109da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 2110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces( 21139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const sp<const DisplayDevice>& displayDevice, const Region& dirty) 2114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposeSurfaces"); 21169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 21179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 21189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 21199f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 oldColorMatrix; 21209f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) && 21219f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform); 21229f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 21239f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mat4 colorMatrix = mColorMatrix * mDaltonizer(); 21249f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); 21259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 21269f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 21279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool hasClientComposition = mHwc->hasClientComposition(hwcId); 21289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasClientComposition) { 21299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("hasClientComposition"); 2130a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 21319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) { 2132c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 21339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getDisplayName().string()); 21343f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 21353f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 21363f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 21373f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 21383f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 2139c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 2140a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2141a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 21429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId); 21439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasDeviceComposition) { 2144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 2145b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 2146b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 21473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 2148b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->clearWithColor(0, 0, 0, 0); 2150b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 2151766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 21529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region bounds(displayDevice->getBounds()); 2153766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2154766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 2155766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 2156766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region letterbox(bounds.subtract(displayDevice->getScissor())); 2158766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2159766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 21609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Region region(displayDevice->undefinedRegion.merge(letterbox)); 2161766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2162766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 2163766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 2164766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2165b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 216687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 2167b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 21689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza drawWormhole(displayDevice, region); 2169b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 2170a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 2171f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 21729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 2173766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 2174f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 2175f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 21769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& bounds(displayDevice->getBounds()); 21779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& scissor(displayDevice->getScissor()); 2178f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 2179f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 2180f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 2181f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 21823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2183f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 21849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const uint32_t height = displayDevice->getHeight(); 21859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->setScissor(scissor.left, height - scissor.bottom, 21863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 2187f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 2188f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 218985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 21904b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 219185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 219285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 219385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 21944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 21959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Rendering client layers"); 21969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& displayTransform = displayDevice->getTransform(); 21979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 219885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 21999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza bool firstLayer = true; 22009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 22019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region clip(dirty.intersect( 22029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 22039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Layer: %s", layer->getName().string()); 22049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Composition type: %s", 22059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza to_string(layer->getCompositionType(hwcId)).c_str()); 220685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza switch (layer->getCompositionType(hwcId)) { 22089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Cursor: 22099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Device: 22109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::SolidColor: { 2211ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 22129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getClearClientTarget(hwcId) && !firstLayer && 22139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->isOpaque(state) && (state.alpha == 1.0f) 22149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza && hasClientComposition) { 2215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 2216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 22179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->clearWithOpenGL(displayDevice, clip); 2218cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 221985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 222085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 22219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza case HWC2::Composition::Client: { 22229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 222385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 2224a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 22259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza default: 2226da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 2227cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 22289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } else { 22299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV(" Skipping for empty clip"); 2230a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 22319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza firstLayer = false; 223285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 223385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 223485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 22359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 223685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 22379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayTransform.transform(layer->visibleRegion))); 223885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 22399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->draw(displayDevice, clip); 224085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 22414b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 22424b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 2243f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 22449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (applyColorMatrix) { 22459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza getRenderEngine().setupColorTransform(oldColorMatrix); 22469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 22479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 2248f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 22499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mRenderEngine->disableScissor(); 22503f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 225455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 22553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 22563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 2257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22597d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 2260ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 22616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 226213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 22631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 22647d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 22657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 22667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 22677d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) { 22687d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 22697d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22707d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mCurrentState.layersSortedByZ.add(lbc); 22717d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 22727d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 22737d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 227496f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 2275ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 22764f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 22777d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 227896f0819f81293076e652792794a961543e6750d7Mathias Agopian} 227996f0819f81293076e652792794a961543e6750d7Mathias Agopian 228022851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) { 228196f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 228222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza sp<Layer> layer = weakLayer.promote(); 228322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza if (layer == nullptr) { 228422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza // The layer has already been removed, carry on 228522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza return NO_ERROR; 228622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza } 228722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza 2288598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 2289598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (index >= 0) { 2290598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersPendingRemoval.push(layer); 2291598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch mLayersRemoved = true; 2292598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch setTransactionFlags(eTransactionNeeded); 2293598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return NO_ERROR; 2294598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch } 2295598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch return status_t(index); 2296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2298c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 2299dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 2300dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 2301dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 23023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 2303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 2304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 2307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 2308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 230999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 2312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23148b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 23158b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 23168b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 23178b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 23188b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 23197c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2320698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 232128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2322e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 23232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 23242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 23252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 23262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 23277c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 23282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 23292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 23307c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 23317c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 23327c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 23332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 23342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 23352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2339e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2342e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2343b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2344b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2346698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2347698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2348d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2349d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2350d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2351d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2352d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2353d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2354d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2355d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2356097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2357d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2358d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2359d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2360d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2361d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2362d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2363d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2364d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2366386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 23672a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // If a synchronous transaction is explicitly requested without any changes, 23682a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // force a transaction anyway. This can be used as a flush mechanism for 23692a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr // previous async transactions. 23702a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr if (transactionFlags == 0 && (flags & eSynchronous)) { 23712a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr transactionFlags = eTransactionNeeded; 23722a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr } 23732a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr 237428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2375ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 2376ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags); 2377ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2378468051e20be19130572231266db306396a56402bIrvel 2379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 238028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2381698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 23852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 23862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 23872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 23882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2389386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 23902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2391386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2392386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2393386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2394386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 23952d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 23962d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2397386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2398386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2399cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 24059a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 24069a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 24079a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 24089a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 24109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 24113ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2414097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2420e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2421e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 242500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2427e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2428e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2432e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2433e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2434e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2436e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 243947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 244047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 244147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 244247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 244347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 244447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 244547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 244647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 244747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 244847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2449e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 245813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 246199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr bool geometryAppliesWithResize = 246299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr what & layer_state_t::eGeometryAppliesWithResize; 2463e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 246499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) { 2465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 246682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr } 2467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 247147db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayer(s.z) && idx >= 0) { 2472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2480e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2481e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2482e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2483e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2484e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 24859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->setAlpha(s.alpha)) 2486e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2496231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza if (what & layer_state_t::eFlagsChanged) { 2497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 250199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr if (layer->setCrop(s.crop, !geometryAppliesWithResize)) 2502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2504acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (what & layer_state_t::eFinalCropChanged) { 2505acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos if (layer->setFinalCrop(s.finalCrop)) 2506acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos flags |= eTraversalNeeded; 2507acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos } 2508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 251147db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos if (layer->setLayerStack(s.layerStack) && idx >= 0) { 2512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 25197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza if (what & layer_state_t::eDeferTransaction) { 25207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza layer->deferTransactionUntil(s.handle, s.frameNumber); 25217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // We don't trigger a traversal here because if no other state is 25227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // changed, we don't want this to cause any more work 25237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza } 2524c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr if (what & layer_state_t::eOverrideScalingModeChanged) { 2525c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr layer->setOverrideScalingMode(s.overrideScalingMode); 2526c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // We don't trigger a traversal here because if no other state is 2527c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr // changed, we don't want this to cause any more work 2528c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr } 2529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 25334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 25340ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 25350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 25364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 25374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2540921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 25416e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 25424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 25436e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 25448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 25454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 25464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 25474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 25484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 25493165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 25503165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 25514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 25524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 25534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 25553165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 25564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 25574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 25584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 25594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 25604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 25614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 25667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25687d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 25697d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza result = addClientLayer(client, *handle, *gbp, layer); 25707d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 25717d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 25727d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 2573ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceCreation(layer); 25747d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 25757d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 25764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 25804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 25814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 258492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 25908f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 25954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 25964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 25974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2598b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 26004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 26014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 26024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 26064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 26074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 26094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 26104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2611b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 26124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2613118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2614118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2615ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 26169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 26176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 26186710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 26196710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 26206710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 2621ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.saveSurfaceDeletion(l); 26226710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 26236710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 26246710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 26259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 26269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 26279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 26289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 262913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 26316710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 26326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 263322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza return removeLayer(layer); 2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 263813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 263901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 264013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 264113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 264213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 264301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 264401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2645692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 264601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 264713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 26484c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 26494c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 265047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 265147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 265213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 265313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 26556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 26569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 26579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 26586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 265913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 266013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 266113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 266213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 266313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 266413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 2665c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 266613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 266713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 266813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 266913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 267013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 267113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 267213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 267313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 267413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 26752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 26772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 26782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 26792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 26802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 268113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 26822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 26832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2684c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2685c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2686c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 26872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 26882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 26892c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 26902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 26912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2692c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2693ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (mInterceptor.isEnabled()) { 2694ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel Mutex::Autolock _l(mStateLock); 2695ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken()); 2696ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (idx < 0) { 2697ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ALOGW("Surface Interceptor SavePowerMode: invalid display token"); 2698ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel return; 2699ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2700ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); 2701ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 2702ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel 27032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 2704f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn on the display 27052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2706c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2707c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2708c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2709948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2710c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 2713b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 27142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 2715f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2716f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2717f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray param.sched_priority = 1; 2718f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { 2719f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_FIFO on display on"); 2720f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 27212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2722f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn off the display 2723f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 2724f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { 2725f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_OTHER on display off"); 2726f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 2727f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 2728c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2729948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2730948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2731cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2732cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2733cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2734c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 27352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 27362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 27372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 27382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 27392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2740b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 27442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2745db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2746db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 27472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2748b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 27492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 27502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 27512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2752b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 27532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2754db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 27552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 27567306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 27579e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 27582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 27592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2760db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 27612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2762db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2763b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2764b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2765b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2767db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2768b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2769b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2770b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2771b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 277599b49840d309727678b77403d6cc9f920111623fMathias Agopian 2776bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2777bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2778bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2779bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2780bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 278174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2782bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2784fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 27859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 27869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 2787fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 2788fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 27899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 2790fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 2791fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 2792fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 27939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 27949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 279582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 279682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 279725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 279825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 279925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 280025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 280125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 280274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 280335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 280425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 280525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 280625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 280725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 280882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 280974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 281035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 281182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 281225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 281325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 281425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 281525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 281674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 281735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 281825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2819c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2820c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2821c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2822c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2823c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2824c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2825c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2826b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2827b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 2828b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 2829b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 2830b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2831b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 2832b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 283340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 283440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos if ((index < numArgs) && 283540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos (args[index] == String16("--fences"))) { 283640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos index++; 283740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos mFenceTracker.dump(&result); 283840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos dumpAll = false; 283940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos } 2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 28411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 284282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 284374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 284482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 284548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 284682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 284782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 284848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 284982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 285082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 285182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 285282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 285348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2854c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2855c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 285625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 285725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 285825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 285925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 286013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 286174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 286225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 286325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 286425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 286582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 286674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 286782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 286882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 286982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 287082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 287182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 287282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 287348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 28749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 28759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 287686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 28774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 28784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2879d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 28804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 28814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 28824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 28834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 288413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 28854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2886d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 28874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 288882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 288982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 289082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2891ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 289225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2893c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 289425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 289525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 289625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 289725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 289825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 289925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 290025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 290125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 290225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 290325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 290413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 290525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2906d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 290725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 290825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 29094b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2910d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 291125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 291225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 29136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 29146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 29156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 29166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 29176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 29186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 29196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 29206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 29216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 29226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 29236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 29246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 29256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 29264803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 29274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 29284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 29294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 29304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 29314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 29324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 29334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 29344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 29354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 29364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 29374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 29384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 29394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 29404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 29414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 29424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 2943b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 2944b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 2945b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 2946b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { 2947b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[b] / 1e9; 2948b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2949b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[b]) / mTotalTime; 2950b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 2951b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 2952b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 2953b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; 2954b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2955b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; 2956b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 2957b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza NUM_BUCKETS - 1, bucketTimeSec, percent); 2958b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 2959b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2960e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName, 2961e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>&& history) { 2962e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 2963e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza auto& stats = mBufferingStats[layerName]; 2964e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& segment : history) { 2965e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (!segment.usedThirdBuffer) { 2966e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.twoBufferTime += segment.totalTime; 2967e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2968e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (segment.occupancyAverage < 1.0f) { 2969e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime += segment.totalTime; 2970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else if (segment.occupancyAverage < 2.0f) { 2971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime += segment.totalTime; 2972e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2973e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++stats.numSegments; 2974e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime += segment.totalTime; 2975e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2976e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 2977e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 2978e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const { 2979e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("Buffering stats:\n"); 2980e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append(" [Layer name] <Active time> <Two buffer> " 2981e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza "<Double buffered> <Triple buffered>\n"); 2982e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza Mutex::Autolock lock(mBufferingStatsMutex); 2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza typedef std::tuple<std::string, float, float, float> BufferTuple; 2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::map<float, BufferTuple, std::greater<float>> sorted; 2985e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& statsPair : mBufferingStats) { 2986e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const char* name = statsPair.first.c_str(); 2987e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferingStats& stats = statsPair.second; 2988e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (stats.numSegments == 0) { 2989e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza continue; 2990e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 2991e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = ns2ms(stats.totalTime) / 1000.0f; 2992e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float twoBufferRatio = static_cast<float>(stats.twoBufferTime) / 2993e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime; 2994e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float doubleBufferRatio = static_cast<float>( 2995e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime) / stats.totalTime; 2996e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float tripleBufferRatio = static_cast<float>( 2997e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime) / stats.totalTime; 2998e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza sorted.insert({activeTime, {name, twoBufferRatio, 2999e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza doubleBufferRatio, tripleBufferRatio}}); 3000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3001e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& sortedPair : sorted) { 3002e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = sortedPair.first; 3003e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferTuple& values = sortedPair.second; 3004e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.appendFormat(" [%s] %.2f %.3f %.3f %.3f\n", 3005e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<0>(values).c_str(), activeTime, 3006e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<1>(values), std::get<2>(values), 3007e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<3>(values)); 3008e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 3009e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("\n"); 3010e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 3011e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 3012e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 301374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 301474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 301582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 30163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 30173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 30183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 30193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 30203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 30213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 30223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 30233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 30243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 302582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 302682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 302782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 302882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 302982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 303082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 3031bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 303282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 30334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 30344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 30353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 30363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 30374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 30383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 30404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 30414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 30424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 30434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 30443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 3045ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 30463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 3047ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 3048ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 3049ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 30509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 30519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 305241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 305341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 305441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 305524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 305624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 30579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, 30589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod()); 305941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 306041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 3061b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 3062b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3063b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 3064b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 3065b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3066e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza dumpBufferingStats(result); 3067e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 30684803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 306982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 307082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 307182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 307282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 30733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 307486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 30753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 307682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 307713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 30783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 307982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 3080bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 308182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 30825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 30835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 30845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 30853e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 308686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 30873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 30885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 30895f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 309074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 30915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 30925f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 30935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 309482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 309582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 30961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 30973e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 309874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 30993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 3101888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 31024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 3103ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 31043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 31053e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 31063e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 31073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 3109ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 3110ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 3111875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 31129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 31134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 31142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 31152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 311674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 311782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 311882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 3119c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 312082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 312182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 3122ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 3123ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 3124ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 312582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 312682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 3127c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 31289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1e9 / activeConfig->getVsyncPeriod(), 31299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiX(), 31309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiY(), 3131ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 313282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 313374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 313482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 313582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 313674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 313782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 313882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 313982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 314082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 314182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 314274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 3143e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3144e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3145e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza /* 3146e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza * HWC layer minidump 3147e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza */ 3148e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t d = 0; d < mDisplays.size(); d++) { 3149e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 3150e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza int32_t hwcId = displayDevice->getHwcDisplayId(); 3151e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 3152e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza continue; 3153e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3154e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 3155e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.appendFormat("Display %d HWC layers:\n", hwcId); 3156e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza Layer::miniDumpHeader(result); 3157e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t l = 0; l < count; l++) { 3158e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<Layer>& layer(currentLayers[l]); 3159e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza layer->miniDump(result, hwcId); 3160e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 3161e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 3162e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 316382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 316482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 316582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 316682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 31673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 316874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 31693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 31709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza bool hwcDisabled = mDebugDisableHWC || mDebugRegion; 31719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza result.appendFormat(" h/w composer %s\n", 31729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcDisabled ? "disabled" : "enabled"); 317374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 317482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 317582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 317682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 317782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 317882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 317982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 3180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 318213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 318348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 3184db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 318548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 318648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 318748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 318848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 318948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 319048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 319148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 319248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 319348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 319448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 319548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 319648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 319748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 3198cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 3199cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 320063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 320163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 320263f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 320363f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 320463f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 320563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 320663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 320763f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 320863f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 320924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 321063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 321163f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 321263f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 321363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 321463f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 321563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 321663f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 321763f165fd6b86d04be94d4023e845e98560504a96Keun young Park 32186e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { 3219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 3220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 3221041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 3222698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 3223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 3224d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 3225d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 32262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 3227c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza case GET_HDR_CAPABILITIES: 3228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 3229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 3230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 3231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 3232a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 32333bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 323499b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 32356e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3236375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 3237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 32391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 32401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 32411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 32421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 32431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 32441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 32451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 324699b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 324799b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 32486e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid); 32491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 32501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 32511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 3252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32546e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return OK; 32556e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard} 32566e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard 32576e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact( 32586e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 32596e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{ 32606e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard status_t credentialCheck = CheckTransactCodeCredentials(code); 32616e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard if (credentialCheck != OK) { 32626e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return credentialCheck; 32636e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard } 32641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 3266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 3267b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 326899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 3269375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3270375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 3271375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 3272e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 3273375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 3274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 3275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 3277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 327801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 327935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 3280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 3283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 328453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 328553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 328853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 3289cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3290cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 3291cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 3292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 3293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 3294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 3295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 3296cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 3297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 32984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 32994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 33004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 33014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 330253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 330353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 330453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 330553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 330653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 330753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 3308a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 3309a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 3310a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 3311a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 3312a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 3313a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 3314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 331501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 3316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 3317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 3318b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 331912839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 3320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 3321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 3322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 33234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 33244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 3325ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 3326ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3327ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 3328ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 3329ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 3330ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 33319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 1: 33329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Protanomaly); 33339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 2: 33359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); 33369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 3: 33389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Tritanomaly); 33399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 33409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza default: 33419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::None); 33429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 3343ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3344ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 33459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Correction); 3346ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 33479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Simulation); 3348ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 3349ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 3350ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 33519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 33529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33539c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 33549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 33559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 33569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 33579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 33589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 33599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 3360794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 33619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza for (size_t j = 0; j < 4; j++) { 33629f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mColorMatrix[i][j] = data.readFloat(); 33639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 33649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 33669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 33679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 33689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 33699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 33709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 3371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3372f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 3373f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 3374f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 3375645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 3376645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 3377f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 3378f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 3379ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 3380ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 3381ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 3382ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 3383ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 3384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 3385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 3390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3394468051e20be19130572231266db306396a56402bIrvel case 1020: { // Layer updates interceptor 3395468051e20be19130572231266db306396a56402bIrvel n = data.readInt32(); 3396468051e20be19130572231266db306396a56402bIrvel if (n) { 3397468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor enabled"); 3398ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays); 3399468051e20be19130572231266db306396a56402bIrvel } 3400468051e20be19130572231266db306396a56402bIrvel else{ 3401468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor disabled"); 3402468051e20be19130572231266db306396a56402bIrvel mInterceptor.disable(); 3403468051e20be19130572231266db306396a56402bIrvel } 3404468051e20be19130572231266db306396a56402bIrvel return NO_ERROR; 3405468051e20be19130572231266db306396a56402bIrvel } 34068cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza case 1021: { // Disable HWC virtual displays 34078cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza n = data.readInt32(); 34088cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !n; 34098cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza return NO_ERROR; 34108cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 3411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 3414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 341653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 341787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 341899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 341953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 342053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 342159119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 34222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 34232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 342459119e658a12279e8fff508f8773843de2d90917Mathias Agopian 34252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 34262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 34272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 3428b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 3429b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 3430b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 3431b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 34322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 34332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 3434b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 3435b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 3436b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 3437b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3438b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 3439b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 3440b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 3441b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 3442b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3443b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 3444b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 3445b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 3446b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 3447b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 34482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 34492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 34502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 34512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 34522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 3453b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 34542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 34552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 34562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 34572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 34592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 34602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 34612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 34622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3464b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 3465b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 3466b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 34672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 34682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 3469c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 34702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 34712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 34722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 34732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 3474b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 3475b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 3476b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 3477b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 34782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 34802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 3481b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 3482b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 3483b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 34842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 34852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 34862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 3487c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 34882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 34892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 34902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3491b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 34922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 34932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 34942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 3495b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 3496b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 3497b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 3498b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 3499097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 35002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 3501b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 35022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 35032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 3507c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 3508b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 3509b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 351053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos result(NO_ERROR), 3511b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 351253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos exitRequested(false), 351353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos code(0), 351453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos data(NULL), 351553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos reply(NULL) 3516b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 3517b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 3518b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 35232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 35242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 3526b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 35272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 3528aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 35292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 3530b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 3531b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 3532b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 35332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 35342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 35352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 35362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 35382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 35392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3540c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3541c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3542c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 35432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 35452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 35462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 35482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 35492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 35505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 35515ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 35525ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 3553b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder(); 35545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 3555c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 3556c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 3557c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 3558c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 3559c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3560c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3561c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3562c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3563c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3564c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3565c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3566c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3567c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3568c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3569c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3570c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3571c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3572c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3573c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3574c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3575c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 35762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 35772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 35782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 35792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3580c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 35812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 35822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3583c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3584c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 35852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 3586b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot; 35872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 35882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 35892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 35902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3591c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3592c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3593b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, 3594b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos Transform::orientation_flags rotation, 3595b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 35962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3597c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 35982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3599c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3600b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos rotation(rotation), result(PERMISSION_DENIED), 3601b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos isLocalScreenshot(isLocalScreenshot) 36022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 36032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 36082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 36092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3610c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3611c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3612b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotation, isLocalScreenshot); 3613097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 36142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 36152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 36172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 36182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 36192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 36202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 36212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 36222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 36232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 36242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 36252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 36262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3627c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3628b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos useIdentityTransform, rotationFlags, isLocalScreenshot); 36292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 36302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 36312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 36322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 36332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 36342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3635118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3636118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3637180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3638180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3639180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3640c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3641180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 3642c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3643180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3644180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 36453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3646180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3647180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 364889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 364989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 365089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 36510e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 3652180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3653c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3654c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3655c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3656c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3657c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3658c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3659c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3660c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3661c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3662c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3663c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3664be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3665be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3666c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3667c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3668c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3669c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3670be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3671be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3672c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3673c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3674180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 36753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3676180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3677180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3678c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3679c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 36803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3681180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3682180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 36833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3684180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3685180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3686180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3687180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3688180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 36891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3690180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3691180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3692180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3693180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3694c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3695180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3696180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3697180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3698180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3699180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3700180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3701931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3702180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3703180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3704180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 37052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 37062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 37072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3708c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3709c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3710b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool useIdentityTransform, Transform::orientation_flags rotation, 3711b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool isLocalScreenshot) 371274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3713fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3714fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3715180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 37163502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_w = hw->getWidth(); 37173502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_h = hw->getHeight(); 37183502416204d9dbd905012ee586d8bd145323809fDan Stoza 37193502416204d9dbd905012ee586d8bd145323809fDan Stoza if (rotation & Transform::ROT_90) { 37203502416204d9dbd905012ee586d8bd145323809fDan Stoza std::swap(hw_w, hw_h); 37213502416204d9dbd905012ee586d8bd145323809fDan Stoza } 3722180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3723180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3724180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3725180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3726180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3727180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3728180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3729180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3730180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3731180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3732b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool secureLayerIsVisible = false; 3733b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const LayerVector& layers(mDrawingState.layersSortedByZ); 3734b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const size_t count = layers.size(); 3735b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos for (size_t i = 0 ; i < count ; ++i) { 3736b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const sp<Layer>& layer(layers[i]); 3737b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos const Layer::State& state(layer->getDrawingState()); 3738b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ && 3739b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos state.z <= maxLayerZ && layer->isVisible() && 3740b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos layer->isSecure()) { 3741b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos secureLayerIsVisible = true; 3742b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3743b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3744b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 3745b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos if (!isLocalScreenshot && secureLayerIsVisible) { 3746b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos ALOGW("FB is protected: PERMISSION_DENIED"); 3747b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos return PERMISSION_DENIED; 3748b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 3749b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 37500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 37510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 375283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 3753605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 3754605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Put the screenshot Surface into async mode so that 3755605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // Layer::headFenceHasSignaled will always return true and we'll latch the 3756605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // first buffer regardless of whether or not its acquire fence has 3757605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // signaled. This is needed to avoid a race condition in the rotation 3758605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos // animation. See b/30209608 3759605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos sur->setAsyncMode(true); 3760605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos 37610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 376274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 37635a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 37645a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine if (result == NO_ERROR) { 37653ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 37663ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 37672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 37680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 37690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 37704ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 37710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 37720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 37732a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 37740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 37750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 37760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 37770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 37780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 37790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 37800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3781866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 37820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 37830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 37840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 37850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 37860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 37873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 37883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 37893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 37903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 37910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 37920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 37930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 37940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3795c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3796c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3797c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3798d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3799866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3800866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3801866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3802866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3803866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3804866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 38059707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 38069707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3807866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3808866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3809866399093f9f60e7305f291e688abb456bace710Riley Andrews } 38102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3811866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3812866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3813866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3814866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3815866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3816866399093f9f60e7305f291e688abb456bace710Riley Andrews } 38172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3818866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3819866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3820866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3821866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3822866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3823866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3824866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3825866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3826866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3827866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3828866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3829866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3830866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3831866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 38322d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3833866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 38342d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 38352d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3836d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3837d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3838d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3839d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3840d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3841d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3842d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3843d555684cb36dfb959694db76962e570184f98838Mathias Agopian 38440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 38460aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 3847f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu window->cancelBuffer(window, buffer, syncFd); 3848f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu buffer = NULL; 38490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 38500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 38510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 38520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 385474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3855f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu if (buffer) { 3856f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu // queueBuffer takes ownership of syncFd 3857f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu result = window->queueBuffer(window, buffer, syncFd); 3858f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu } 385974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 38600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 38610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 386274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 38630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 386474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 386574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 386674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 386774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 386874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3869d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3870d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3871fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3872d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3873d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3874d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3875fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3876fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3877fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3878fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3879fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3880fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3881fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3882fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3883fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3884fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3885fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3886fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3887fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3888fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 38899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", 3890fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3891fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3892fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3893fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3894fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3895fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3896fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 3897ce796e78a57018f186b062199c75d94545318acaPablo Ceballosbool SurfaceFlinger::getFrameTimestamps(const Layer& layer, 3898ce796e78a57018f186b062199c75d94545318acaPablo Ceballos uint64_t frameNumber, FrameTimestamps* outTimestamps) { 3899ce796e78a57018f186b062199c75d94545318acaPablo Ceballos return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps); 3900ce796e78a57018f186b062199c75d94545318acaPablo Ceballos} 3901ce796e78a57018f186b062199c75d94545318acaPablo Ceballos 39021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 39031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3904921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3905921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3906921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3907921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 390813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3909921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3910921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3911921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3912921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3914be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 391513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 391613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3917be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 39181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 39191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3920be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3921be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3922be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 39231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 39241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3925be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3926be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3927be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3928be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3929921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3930921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 39323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 39353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 39363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 39373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 39383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 39393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 39403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3941