SurfaceFlinger.cpp revision ee44edd0acccbf5eaa918d75737c3b65ee04fff7
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 171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 2486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h> 25b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h> 26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 3867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h> 39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 45392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 51cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 57921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 58ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 640f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 65faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 66d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 67d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 73a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 78875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 89ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 90ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12499b49840d309727678b77403d6cc9f920111623fMathias Agopian 12599b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12699b49840d309727678b77403d6cc9f920111623fMathias Agopian 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 134875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 137a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 1384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 142a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 147ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 148ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 149faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 150948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 1519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mDaltonize(false), 1529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix(false) 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 154a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1588afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 159b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 16050210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 161b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1668afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1678afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 17063f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 17163f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 173c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 174c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 18099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 18199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 185a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 186a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 189c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 19199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 19299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 19413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 197a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2007e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20296f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 20396f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 20496f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 20596f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 20696f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 211dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 212dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 2313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 2328dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 233dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 268e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2699e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 273692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 286a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2873330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 293921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 298a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 299a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 303921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 306921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 318faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 319faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3205167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3215167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const char* label) : 3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mPhaseOffset(phaseOffset), 3240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncOnLabel(String8::format("VsyncOn-%s", label)), 3265167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncEventLabel(String8::format("VSYNC-%s", label)), 3270a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mDispSync(dispSync) {} 328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // Do NOT lock the mutex here so as to avoid any mutex ordering issues 333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // with locking it in the onDispSyncEvent callback. 334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3350a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis status_t err = mDispSync->addEventListener(mPhaseOffset, 336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3415167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3495167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 364a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3650a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 3675167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 3680a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 3780a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const nsecs_t mPhaseOffset; 3790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 3805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 3815167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 3820a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex mMutex; 386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 388faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 391a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall Mutex::Autolock _l(mStateLock); 393692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 39634a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 402b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 403875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // get a RenderEngine for the given display / config (can't fail) 40405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); 405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 407875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 411da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4139e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 415f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // set-up the displays that are already connected 4169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 418dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool isSecure = true; 419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked(type); 420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 421692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> producer; 423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> consumer; 424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza 427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, 428b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza consumer); 42919e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall int32_t hwcId = allocateHwcDisplayId(type); 430f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 43119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall type, hwcId, mHwc->getFormat(hwcId), isSecure, token, 432b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza fbs, producer, 43305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 43886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGD("marking display %zu as acquired/unblanked", i); 4392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(HWC_POWER_MODE_NORMAL); 440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 442f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 444cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // make the GLContext current so that we can create textures when creating Layers 446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // (which may happens before we render something) 447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 448a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 449028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4515167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden vsyncPhaseOffsetNs, true, "app"); 452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mEventThread = new EventThread(vsyncSrc); 4530a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden sfVsyncPhaseOffsetNs, true, "sf"); 4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mSFEventThread = new EventThread(sfVsyncSrc); 4560a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mEventQueue.setEventThread(mSFEventThread); 457028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 460d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // set a fake vsync period if there is no HWComposer 462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mHwc->initCheck() != NO_ERROR) { 463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(16666667); 464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 465faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 46792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 47113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 472a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 473a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 4779e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ? 4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 4803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 486a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 496d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 4982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 500097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 5016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 503134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (configs == NULL) { 5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5107aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 5117aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 5127aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 513692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5149e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 515692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5201604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5211604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5221604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 523c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5411604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const Vector<HWComposer::DisplayConfig>& hwConfigs = 5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza getHwComposer().getConfigs(type); 5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza for (size_t c = 0; c < hwConfigs.size(); ++c) { 5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const HWComposer::DisplayConfig& hwConfig = hwConfigs[c]; 5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float xdpi = hwConfig.xdpi; 5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float ydpi = hwConfig.ydpi; 5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 5737f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 5747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 5771604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.w = hwConfig.width; 5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.h = hwConfig.height; 5817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 5827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.fps = float(1e9 / hwConfig.refresh); 58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden 58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 59691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 59791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 59891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.presentationDeadline = 59991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->push_back(info); 6058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 609dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 61089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 61167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 61267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 61367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 61467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 61567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 61667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 61767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 61867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 61967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 62067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 62167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 62267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 6236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 62424a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza sp<DisplayDevice> device(getDisplayDevice(display)); 62524a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 62624a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 62724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 62824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 630dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 6446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 6496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 6546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 6556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 6566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 6576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 6586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 6596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 6606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 6617306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 6627306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 663784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 6649ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 6657306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 6667306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 6707306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 6766c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6776c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 6786c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6796c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 6806c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 6816c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 682888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 683c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 684c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 685d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 686d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 687d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 688d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 689d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 690d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 691d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 692d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 693d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 694d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 695d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 696d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 697d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 698d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 699d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 7008aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 701bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 702bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 71599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 72099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 722c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 72699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 727c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 72899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 72999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 73099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 73199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 73299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 73399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7354f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 7364f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 7374f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 7384f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 73999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 741faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 742faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 743948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 744faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 745d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 746d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 747faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 74843601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 749faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 750faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 752faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 753faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 754948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 755948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 756948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 757948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall ALOGE("resyncToHardwareVsync called when HW vsync unavailable"); 758948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 759948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 760948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const nsecs_t period = 762faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 763faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 764faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 766faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 767faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 768faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 769d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 770d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 771faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 772faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 773faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 774faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 775948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 776faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 777faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 778d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 779d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 780faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 781faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 782faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 783948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 784948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 785948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 786faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 787faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 788faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 789d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 790faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 791d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 792d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 793d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 794d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 795faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 796148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 797d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 798d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 799d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 800d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 801d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 802d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 803148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 804148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 805148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 806148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 807148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 808148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 809148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 810148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 811148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 812148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 8139e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8149e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 8159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 816692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 817692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 8189e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 819692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 820692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 8219e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 8229e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 8239e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8249e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 8253ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 8268630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8278630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 82881cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 829faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 83081cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 8318630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8328630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 8341c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 83599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 8366b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::TRANSACTION: { 8376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageTransaction(); 8386b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 8396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 8406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 8416b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 8426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 8435878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 8446b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 8455878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 8465878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 8475878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 8486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 8496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 8506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 8516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 8526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 8536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 8546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 8556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 8564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8596b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 8614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 86287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 8636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 8644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 8656b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 8664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8686b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 8706b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 8714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 8723a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 8734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 884cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 885cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 887cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 897cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 899cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 900cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 9013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 9023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 9033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 905da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 907cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 908cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 909cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 910cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 911cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 915bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 916bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 917bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 918bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 919bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 920bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 922cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 923cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 925cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 9261eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 928cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 930cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 931cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 932cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 933cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 934cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 935cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 936cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 937a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 938cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 939cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 9401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 942cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian layers[i]->onPostComposition(); 944cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 9454b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 946faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const HWComposer& hwc = getHwComposer(); 947faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 948faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 949faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 950faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 951faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 952faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 953948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 954faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 955faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 956faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9575167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 958faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 9592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 960faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 961faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 962faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 963faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 9644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 9654b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 9664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 967a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 9684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 9694b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 9704b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 9714b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 9724b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 9734b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 9744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 9754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 9764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 977cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 978cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 979cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 98152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 982cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 98387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 98487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 985ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 9861eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 98792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 988ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 989ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 99013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Vector< sp<Layer> > layersSortedByZ; 9914297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 9927e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 9937e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 9942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 9951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 996ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 9977e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 9981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 999ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 10011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1002ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 1003a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 1004a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 1005a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 1006a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 1007ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 1008ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 100987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 101087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 10113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 10124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 10137e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 10147e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 10157e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 10163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 10173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1018cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 10193b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1020cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 1021028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1022b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1023b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1024b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1025b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1026b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1027b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1028b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1029b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1030b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1031b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1032b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1033b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1034b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1035b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1036b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1037b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1038b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1039b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1040b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1041b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1042b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 10437143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1044b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1045b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1046b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1047b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1048028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1049028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 105052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 105152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 105252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 1053a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 1054a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 1055a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1056a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 1057a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 1058a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 105913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1060a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 1061a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 1062a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 1063a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1064a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1065a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 106613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1067a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 10689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { 1069a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 1070a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1071a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1072a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1073a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1074a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1075a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1076a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1077a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 107892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 10794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 1080e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 1081e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 108213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1083cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 1084e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 1085a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1086a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1087a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1088a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 1089a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 1090a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 1091a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 109213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1093a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 10941e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 109552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 109687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1097a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 109803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // If possible, attempt to use the cursor overlay on each display. 109903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 110003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 110103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 110203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id >= 0) { 110303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 110403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 110503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 110603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 110703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 110803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 110903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 111003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer->isPotentialCursor()) { 111103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews cur->setIsCursorLayerHint(); 111203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 111303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 111403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 111503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 111603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 111703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 111852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 111952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 112038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 112138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 112238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall sp<const DisplayDevice> hw(mDisplays[dpy]); 112338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall hw->prepareFrame(hwc); 112438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 112552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1126cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 112752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1128cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1129cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 113052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 113192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 11332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1134cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1135cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 113602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 113702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 113802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 113902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1140cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1141cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1142cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 114387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 114452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 11454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 11464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 114752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1152841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1153b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1154a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1155a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1156c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 115752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 1158ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 11592a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 11602a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 11612a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 11622a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 1163875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11642a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 1165e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 116652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 11686da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // make the default display current because the VirtualDisplayDevice code cannot 11696da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // deal with dequeueBuffer() being called outside of the composition loop; however 11706da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // the code below can call glFlush() which is allowed (and does in some case) call 11716da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // dequeueBuffer(). 11726da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 11736da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian 117492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 117613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1177da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 117852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 1179e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1180e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 11811e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 11821e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 118352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1184d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 118552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 118752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1188d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 118952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1190ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1191e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1192e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1193a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1194a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 11956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 11966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 11976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 11986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 11996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1204841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1205841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 12067cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 12077cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 12087cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 12097cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 12107cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 12117cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1212ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1213ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1214ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1215ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1216ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1217ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1218ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1219ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1220ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1221ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 122387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1224ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1225ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1226ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1227ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1228ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 12293d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 123187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 12323d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 12333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 124313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 12543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 125892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 125992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 126092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1262e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 126392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 126592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 126693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 126792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 126892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 126992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 127292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 127592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 12763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 127727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 127827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 127927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 128002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1281875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 128202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 128302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 128402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 12859e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 12867adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 128702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 128892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 128992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 129092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 129192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 129292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 12943ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1295097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1296097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 12971474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 129993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 130093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 130193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 130202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 130302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 130402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 130593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 130693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 130793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 130893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 130993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 131092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 131193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1312db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 131393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 131493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 131593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 131693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 131700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 131800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 131900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 132000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 132100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 13224fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 132393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 132447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 132547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 132647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 132792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 132892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 132992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 133192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 133292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 133392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1335e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1336cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 133799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1338db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1339b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1340b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 1341b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 1342b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 1343db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 134402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall int32_t hwcDisplayId = -1; 134599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 134602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 134702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 134802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 134999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1350db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 13511f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int width = 0; 13521f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int status = state.surface->query( 13531f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_WIDTH, &width); 13541f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 13551f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query width (%d)", status); 13561f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int height = 0; 13571f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza status = state.surface->query( 13581f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_HEIGHT, &height); 13591f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 13601f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query height (%d)", status); 13611f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 || 13621f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza (width <= MAX_VIRTUAL_DISPLAY_DIMENSION && 13631f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) { 13641f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza hwcDisplayId = allocateHwcDisplayId(state.type); 13651f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza } 13661f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza 1367db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface( 1368b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *mHwc, hwcDisplayId, state.surface, 1369b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqProducer, bqConsumer, state.displayName); 1370db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1371db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 137247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 137399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 137499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1375cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1376cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1377cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1378cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 137902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1380cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1381cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1382b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza dispSurface = new FramebufferSurface(*mHwc, state.type, 1383b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqConsumer); 1384b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza producer = bqProducer; 1385cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1386cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1387cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 138899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1389cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 139019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall state.type, hwcDisplayId, 139119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall mHwc->getFormat(hwcDisplayId), state.isSecure, 139205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall display, dispSurface, producer, 139305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1394cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1395cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 13964fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 13978dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1398cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 13991c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (state.isVirtualDisplay()) { 14001c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (hwcDisplayId >= 0) { 14011c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall mHwc->setVirtualDisplayProperties(hwcDisplayId, 14021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getWidth(), hw->getHeight(), 14031c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getFormat()); 14041c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 14051c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } else { 14067adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 14071c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 140893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 140992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 141092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 14158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 14168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 14178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 14188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 14208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 14218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 14238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 14248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 14258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 14278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 14288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 14308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 14318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 14328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 14338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 14358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 14368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 14378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 14388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 14398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 144013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 14411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 14428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 14438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 14448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 14458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 14468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 14478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 14488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 14508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 14518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 14528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 14538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 145491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 14558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 14568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 146091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 146191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 146291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 146391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 146491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 146591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 146691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 146791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 14688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 146991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 14708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 14728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 14738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 14743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 14753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 14763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 14791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 14803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 14813559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 14833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 14843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 14853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 14863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 14873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 14883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 14891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 14903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 14911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 14923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 14933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 14943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 14953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 14963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 14971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 14981501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 14991501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 15001501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 15010aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 150603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 150703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 150803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 150903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 151003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 151103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 151203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer& hwc(getHwComposer()); 151303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 151403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 151503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 151603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id < 0) { 151703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 151803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 151903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 152003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 152103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 152203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 152303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 152403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 152503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) { 152603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 152703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 152803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 152903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect cursorPos = layer->getPosition(hw); 153003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hwc.setCursorPositionAsync(id, cursorPos); 153103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 153203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 153303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 15344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 15354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 15364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 15374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 15384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 15394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 15404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 15414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 15424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 15444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 15464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 15474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 15484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 15494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 15504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 15512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 15522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 15534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 155787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 155887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1560841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1561841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 156687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 157013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 15731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 157501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 157687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 157787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 157887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1579ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1580ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1581ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1583ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1584ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1585ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1586ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1587ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1598a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1599a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1600a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1601a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1602a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1603a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1604a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1605a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1606a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1607a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1608ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1609ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1610da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 16114125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 16125219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian Rect bounds(s.transform.transform(layer->computeBounds())); 1613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 16174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 16184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 16194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 16204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 16212ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = tr.transform(s.activeTransparentRegion); 16224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 16234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 16244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1625a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 16264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 16282ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = s.activeTransparentRegion; 16294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1630ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1632ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 16334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1634ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1635ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1636ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1637ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1638ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 16564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1659a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1668ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1670a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1671ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 16724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 16734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1674ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1675ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 168087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 16848b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1685a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1688a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1689a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 169687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 169792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 16984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 16994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 17004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 170192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 170292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 170387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 170487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 17056b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 170899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 17094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 17101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 17116b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 171251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 171351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 171451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 171551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 171651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 171751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 171851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 171951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 172051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 172151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 172251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Vector<Layer*> layersWithQueuedFrames; 172351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layers.size(); i<count ; i++) { 17241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 17256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 17266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 17276b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 17286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza layersWithQueuedFrames.push_back(layer.get()); 1729ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1730ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 17316b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1732ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1733ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 17346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 173551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner } 173651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { 173751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Layer* layer = layersWithQueuedFrames[i]; 173887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 1739ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 17401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 174187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 17424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 17434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 17443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 17456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 17466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 17476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 17486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 17496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (frameQueued && layersWithQueuedFrames.empty()) { 17506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 17516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 17526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 17536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 17546b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return !layersWithQueuedFrames.empty(); 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1757ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1758ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1759ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1760ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1761ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 176299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 176487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17667143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 17677143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 17687143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 17697143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 17707143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 17717143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 17727143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 17737143316af216fa92c31a60d4407b707637382da1Dan Stoza } 17747143316af216fa92c31a60d4407b707637382da1Dan Stoza 177587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 177687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1777b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 17784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 17810f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 178229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 178329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 178429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 17854297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 17870f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 178829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1789df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 179095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 17910f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 17924297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 179429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 17954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 17964297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { 18013f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if (!doComposeSurfaces(hw, dirtyRegion)) return; 1802ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 1803ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian RenderEngine& engine(getRenderEngine()); 18049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mat4 colorMatrix = mColorMatrix; 18059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDaltonize) { 18069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette colorMatrix = colorMatrix * mDaltonizer(); 18079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 18089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette engine.beginGroup(colorMatrix); 1809ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1810ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian engine.endGroup(); 1811ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 1812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18139c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 18144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1815da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1816da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1817da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18203f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 18223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 182385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 18248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 18251e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 18261e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1827a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1828d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall bool hasGlesComposition = hwc.hasGlesComposition(id); 182985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1830875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) { 1831c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1832c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 18333f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 18343f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 18353f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 18363f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 18373f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 1838c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1839a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1840a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 184185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1842e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1843b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1844b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1845b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 18463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 1847b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 18483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 0); 1849b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1850766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1851766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1852766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1853766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1854766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1855766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1856766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1857766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1858766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1859766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1860766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1861766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1862766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1863766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1864b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 186587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1866b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 186755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1868b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1869a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1870f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1871766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1872766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1873f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1874f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1875f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1876766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1877f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1878f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1879f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1880f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 18813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1882f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 18833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian const uint32_t height = hw->getHeight(); 18843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setScissor(scissor.left, height - scissor.bottom, 18853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 1886f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1887f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 188885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 18894b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 189085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 189185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 189285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 18934b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 189413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); 189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 189685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 189785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 189885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 189985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 190013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 19014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 190285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 190385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 190403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews case HWC_CURSOR_OVERLAY: 190585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 1906ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 190785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 190885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 19094125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden && layer->isOpaque(state) && (state.alpha == 0xFF) 191085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1911cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 191585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 191685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 191785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1918cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 191985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1920a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1921da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1922da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1923da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 192486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i); 1925da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1926da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1927cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1928a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 192985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 193085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 193185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 193285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 193385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 193413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 193585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 193685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 193785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 193885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 193985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 19404b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 19414b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1942f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1943f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 19443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableScissor(); 19453f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 194955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 19503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 19513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1954ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client, 1955ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 19566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 195713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 19581b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 195996f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 1960ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 19614f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 196296f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1963921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1964921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 1965097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 196696f0819f81293076e652792794a961543e6750d7Mathias Agopian} 196796f0819f81293076e652792794a961543e6750d7Mathias Agopian 19683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { 196996f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 197013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 1971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 19726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mLayersPendingRemoval.push(layer); 1973076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 19746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian setTransactionFlags(eTransactionNeeded); 1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1980c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 1981dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1982dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1983dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 19843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 1989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 199199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19968b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 19978b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 19988b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 19998b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 20008b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 20017c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2002698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 200328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2004e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 20052d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 20062d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 20072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 20082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 20097c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 20102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 20112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 20127c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 20137c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 20147c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 20152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 20162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 20172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2021e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2022e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2023e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2024e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2025b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2026b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2027e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2028698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2029698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2030d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2031d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2032d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2033d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2034d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2035d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2036d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2037d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2038097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2039d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2040d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2041d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2042d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2043d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2044d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2045d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2046d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2047698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2048386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 204928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2050386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 205128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2052698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2053386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2054386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2055386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 20562d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 20572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 20592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2060386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 20612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2062386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2063386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2064386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2065386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 20662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 20672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2068386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2069386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2070cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2074e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2075e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 20769a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 20779a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 20789a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 20799a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2080e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 20819a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 20823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2084e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2085097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2086e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2087e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2088e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2089e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2090e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2091e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2092e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2095e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 209600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2099e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2104e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2105e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2107e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2108e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 211047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 211147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 211247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 211347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 211447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 211547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 211647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 211747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 211847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 211947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2120e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2121e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2122e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2123e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2124e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2125e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2126e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2127e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 212913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2132e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 2133e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 2134e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2135e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2136e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2137e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2138e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2139e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 2140e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2141e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2142e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2143e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2144e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2145e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2146e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2147e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2148e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2149e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2150e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2151e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2152e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 2153e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 2154e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2155e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2156e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2157e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2158e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2160e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2161e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 21644125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if ((what & layer_state_t::eVisibilityChanged) || 21654125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden (what & layer_state_t::eOpacityChanged)) { 21664125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden // TODO: should we just use an eFlagsChanged for this? 2167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 2171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 2172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2175e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 2178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 21894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 21900ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 21910ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 21924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 21934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 21966e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2197921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 21986e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 21994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 22006e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 22018b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 22024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 22034d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 22054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22063165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 22073165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 22084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 22094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 22104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 22123165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 22134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 22144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 22154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 22164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 22174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 22184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (result == NO_ERROR) { 22236710604286401d4205c27235a252dd0e5008cc08Mathias Agopian addClientLayer(client, *handle, *gbp, layer); 222496f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 2225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 22304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 22314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 223492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 22408f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 22454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 22464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 22474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2248b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 22524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 22564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 22574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 22604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2261b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 22624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2263118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2264118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2265ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 22669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 22676710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 22686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 22696710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 22706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 22716710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 22726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 22736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 22749a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 22759a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 22769a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 22779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 227813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22806710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 22816710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 2282ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 228313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> l(layer.promote()); 2284ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 22856710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 2286e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2287ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2288ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2289ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2292b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2293b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 229413a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 229501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 229613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 229713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 229813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 229901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 230001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2301692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 230201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 230313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 23044c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 23054c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 230647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 230747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 230813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 230913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 23102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 23116547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 23126547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const nsecs_t period = 23136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 23146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 231513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 231613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 231713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 231813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 231913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 232013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 232113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 232213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 232313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 232413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 232513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 232613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 232713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 232813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 232913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 233013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 23312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 23322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 23332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 23342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 23352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 23362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 233713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 23382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 23392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2340c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2341c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2342c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 23442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 23452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 23462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 23472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2348c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 23502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2351c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2352c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2353c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2354948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2355c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 23582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 23592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2360c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2361948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2362948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2363cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2364cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2365cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2366c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 23672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 23682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 23692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 23702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 23712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2372b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 23762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2377db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2378db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 23792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2380b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 23812c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 23822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 23832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2384b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 23852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2386db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 23872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 23887306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 23899e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 23902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 23912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2392db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 23932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2394db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2395b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2396b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2397b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 23982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2399db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2400b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2401b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2402b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2403b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 240799b49840d309727678b77403d6cc9f920111623fMathias Agopian 2408bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2409bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2410bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2411bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2412bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 241374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2414bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2416fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 24179795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 24189795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 2419fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 2420fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 24219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 2422fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 2423fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 2424fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 24259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 24269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 242925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 243025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 243125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 243225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 243325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 243474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 243535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 243625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 243725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 243825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 243925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 244174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 244235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 244382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 244425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 244525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 244625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 244725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 244874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 244935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 245025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2451c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2452c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2453c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2454c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2455c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2456c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2457c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 24591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 246082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 246174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 246282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 246348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 246482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 246582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 246648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 246782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 246882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 246982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 247082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 247148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2472c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2473c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 247425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 247525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 247625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 247725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 247813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 247974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 248025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 248125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 248225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 248382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 248474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 248582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 248682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 248782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 248882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 248982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 249082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 249148b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 24924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const nsecs_t period = 24934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 249486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 24954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 24964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2497d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 24984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 24994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 25004b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 25014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 250213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 25034b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2504d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 25054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 250682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 250782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 250882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2509ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 251025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2511c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 251225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 251325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 251425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 251525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 251625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 251725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 251825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 251925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 252025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 252125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 252213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 252325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2524d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 252525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 252625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 25274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2528d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 252925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 253025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 25316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 25326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 25336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 25346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 25356547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 25366547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 25376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 25386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 25396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 25406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 25416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 25426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 25436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 25444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 25454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 25464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 25474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 25484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 25494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 25504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 25524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 25534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 25554803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 25564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 25574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 25584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 25594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 25604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 256174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 256274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 256382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 25643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 25653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 25663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 25673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 25683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 25693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 25703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 25713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 25723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 257382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 257582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 257682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 257782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2579bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 25814803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 25824803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 25833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 25843e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 25854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 25863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 25874803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 25884803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 25894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 25904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 25914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 25923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2593ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 25943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2595ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2596ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2597ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 259841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 259941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 260041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 260124cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 260224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 260341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS, 260441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY)); 260541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 260641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 26074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 260882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 260982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 261082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 261182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 26123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 261386efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 26143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 261582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 261613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 26173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 261882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2619bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 262082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 26215f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 26225f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 26235f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 26243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 262586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 26263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 26285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 262974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 26305f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 26315f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 26325f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 263382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 263482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 26351b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 26363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 263774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 26383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2640888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 26414297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2642ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 26433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 26443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 26453e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 26463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 2648ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 2649ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 2650875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 26519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 26524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 26532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 265574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 265682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 265782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2658c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 265982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 266082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 2661ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 2662ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 2663ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 266482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 266582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2666c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2667b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2668b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2669ed985574148a938bc3af24442eead313cc62521cMathias Agopian hwc.getDpiY(HWC_DISPLAY_PRIMARY), 2670ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 267182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 267274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 267382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 267482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 267574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 267682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 267782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 267882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 267982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 268082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 268174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 268282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 268382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 268482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 268582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 26863e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 268774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 26883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 268974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" h/w composer %s and %s\n", 269082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 26919c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette (mDebugDisableHWC || mDebugRegion || mDaltonize 26929c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette || mHasColorMatrix) ? "disabled" : "enabled"); 269374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 269482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 269582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 269682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 269782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 269882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 269982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 270213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 270348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 2704db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 270548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 270648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 270748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 270848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 270948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 271048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 271148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 271248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 271348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 271448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 271548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 271648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 271748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 2718cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2719cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 272063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 272163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 272263f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 272363f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 272463f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 272563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 272663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 272763f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 272863f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 272924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 273063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 273163f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 273263f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 273363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 273463f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 273563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 273663f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 273763f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2743041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 2744698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 2746d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 2747d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 27482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 2749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2753a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 275499b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 275599b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2756e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2757375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2758375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 27611b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27621b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 27631b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 27641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 27651b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 27661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 27671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 276899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 276999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2770e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 27711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 27721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 27731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 27741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 27771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2780b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 278199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2782375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2783375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2784375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2785e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2786375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 279101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 279235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 279753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 279853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 280153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2802cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2803cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2804cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2805e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2809cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2810edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 28114d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 28124d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 28134d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 28144d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 281553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 281653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 281753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 281853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 281953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 282053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2821a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2822a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2823a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2824a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2825a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2826a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 282801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2831b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 283212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2833edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2834edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 28364297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 28374297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2838ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 2839ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2840ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 2841ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 2842ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 2843ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 2844ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1: mDaltonizer.setType(Daltonizer::protanomaly); break; 2845ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break; 2846ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 3: mDaltonizer.setType(Daltonizer::tritanomaly); break; 2847ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2848ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 2849ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::correction); 2850ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 2851ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::simulation); 2852ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2853ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonize = n > 0; 2854ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 2855ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 28569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 28579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 28599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 28609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 28619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix = n ? 1 : 0; 28629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 28639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 28649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 28659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 2866794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 2867794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t j = 0; j < 4; j++) { 2868794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette mColorMatrix[i][j] = data.readFloat(); 2869794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette } 28709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 28729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 28739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 28749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 28759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 28769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 2877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2878f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 2879f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 2880f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 2881645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 2882645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 2883f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 2884f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 2885ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 2886ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 2887ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 2888ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 2889ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 2890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 289553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 289687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 289799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 289853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 289953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 290059119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 29012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 29022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 290359119e658a12279e8fff508f8773843de2d90917Mathias Agopian 29042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 29052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 29062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 2907b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 2908b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 2909b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 2910b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 29112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 29122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 2913b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 2914b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 2915b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 2916b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2917b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 2918b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 2919b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 2920b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 2921b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 2922b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 2923b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 2924b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 2925b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 2926b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 29272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 29282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 29292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 29302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 29312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 2932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 29332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 29342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 29352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 29362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 29382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 29392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 29402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 29412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2943b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 2944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 2945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 29462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 29472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 2948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 29492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 29502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 29512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 29522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 2953b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 2954b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 2955b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 2956b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 29572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 29582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 29592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 2960b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 2961b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 2962b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 29632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 29642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 29652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 2966c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 29672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 2970b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 29712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 29722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 29732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 2974b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 2975b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 2976b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 2977b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 2978097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 29792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 2980b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 29812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 29822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 29842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 29852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 2986b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 2987b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 2988b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 2989b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 2990b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitRequested(false) 2991b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 2992b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 2993b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 29942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 29952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 29962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 29972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 29982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 29992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 30002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 3001b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 30022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 3003aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 30042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 3005b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 3006b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 3007b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 30082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 30092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 30102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 30112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 30142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3015c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3016c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3017c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 30182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 30202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 30212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 30232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 30242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30255ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 30265ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 30275ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 3028097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (!IInterface::asBinder(producer)->localBinder()) { 30295ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian Mutex::Autolock _l(mStateLock); 30305ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 30315ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (hw->getSecureLayerVisible()) { 30325ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 30335ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian return PERMISSION_DENIED; 30345ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 30355ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 30365ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 3037c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 3038c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 3039c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 3040c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 3041c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3042c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3043c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3044c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3045c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3046c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3047c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3048c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3049c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3050c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3051c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3052c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3053c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3054c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3055c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3056c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3057c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 30582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 30592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 30602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 30612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3062c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 30632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 30642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3065c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3066c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 30672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 30682a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 30692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 30702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 30712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3072c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3073c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3074c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 30752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3076c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 30772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3078c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3079c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotation(rotation), 30802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian result(PERMISSION_DENIED) 30812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 30822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 30842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 30852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 30872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 30882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3089c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3090c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3091c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3092097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 30932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 30942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 30952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 30962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 30979eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // make sure to process transactions before screenshots -- a transaction 30989eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // might already be pending but scheduled for VSYNC; this guarantees we 30999eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // will handle it before the screenshot. When VSYNC finally arrives 31009eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // the scheduled transaction will be a no-op. If no transactions are 31019eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // scheduled at this time, this will end-up being a no-op as well. 31029eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian mEventQueue.invalidateTransactionNow(); 31039eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian 31042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 31052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 31062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 31072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 31082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 31092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 31102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 31112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 31122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3113c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3114c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotationFlags); 31152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 31162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 31172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 31182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 31192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 31202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3121118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3122118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3123180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3124180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3125180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3126c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3127180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 3128c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3129180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3130180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 31313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3132180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3133180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 313489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 313589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 313689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 31370e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 3138180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3139c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3140c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3141c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3142c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3143c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3144c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3145c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3146c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3147c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3148c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3149c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3150be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3151be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3152c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3153c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3154c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3155c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3156be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3157be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3158c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3159c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3160180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 31613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3162180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3163180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3164c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3165c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 31663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3167180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3168180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 31693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3170180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3171180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3172180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3173180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3174180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 31751eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3176180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3177180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3178180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3179180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3180c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3181180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3182180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3183180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3184180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3185180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3186180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3187180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // compositionComplete is needed for older driver 3188180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian hw->compositionComplete(); 3189931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3190180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3191180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3192180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 31932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 31942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 31952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3196c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3197c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3198c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 319974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3200fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3201fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3202180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 3203180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 3204180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 3205180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3206180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3207180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3208180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3209180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3210180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3211180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3212180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3213180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3214180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 32150aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 32160aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 321783cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 32180aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 321974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 32200aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian status_t result = NO_ERROR; 32210aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) { 32223ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 32233ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 32242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 32250aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 32260aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 32274ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 32280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 32290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 32302a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 32310aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 32320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 32330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 32340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 32350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 32360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 32370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3238866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 32390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 32400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 32410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 32420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 32430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 32443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 32453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 32463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 32473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 32480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 32490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 32500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 32510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3252c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3253c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3254c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3255d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3256866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3257866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3258866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3259866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3260866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3261866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 32629707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 32639707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3264866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3265866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3266866399093f9f60e7305f291e688abb456bace710Riley Andrews } 32672d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3268866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3269866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3270866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3271866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3272866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3273866399093f9f60e7305f291e688abb456bace710Riley Andrews } 32742d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3275866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3276866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3277866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3278866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3279866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3280866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3281866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3282866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3283866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3284866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3285866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3286866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3287866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3288866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 32892d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3290866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 32912d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 32922d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3293d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3294d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3295d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3296d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3297d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3298d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3299d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3300d555684cb36dfb959694db76962e570184f98838Mathias Agopian 33010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 33020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 33030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 33040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 33050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 33060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 33070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 33080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 330974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3310afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall // queueBuffer takes ownership of syncFd 3311866399093f9f60e7305f291e688abb456bace710Riley Andrews window->queueBuffer(window, buffer, syncFd); 331274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 33130aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 33140aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 331574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 33160aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 331774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 331874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 331974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 332074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 332174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3322d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3323d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3324fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3325d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3326d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3327d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3328fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3329fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3330fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3331fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3332fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3333fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3334fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3335fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3336fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3337fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3338fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3339fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3340fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3341fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 334286efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", 3343fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3344fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3345fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3346fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3347fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3348fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3349fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 33501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 33511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3352921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3353921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3354921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3355921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 335613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3357921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3358921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3359921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3360921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3362be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 336313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 336413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3365be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 33661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 33671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3368be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3369be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3370be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 33711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 33721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3373be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3374be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3375be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3376be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3377921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3378921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3379921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3380921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 33813ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 338247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) { 3383e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3384e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 33853ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 338647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) { 3387da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3388da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3389b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 33907303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3391b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 339296f0819f81293076e652792794a961543e6750d7Mathias Agopian 3393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 33943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 33953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 33963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 33973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 33983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 33993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 34003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 34013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 34023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3403