SurfaceFlinger.cpp revision 0a688f5005b512b96d676a7fa6e23be9132a492c
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> 550a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h> 561c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 58921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 59ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 650f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 66faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 67d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 68d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 73a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 74a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 79875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 90ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 91ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12599b49840d309727678b77403d6cc9f920111623fMathias Agopian 12699b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 12799b49840d309727678b77403d6cc9f920111623fMathias Agopian 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1294f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 133076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 135875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 138a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 1394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1418afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 143a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 148ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 149ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 150faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 151948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 1529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mDaltonize(false), 153b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasColorMatrix(false), 154b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff(false), 155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets(), 156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime(0), 157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime(0) 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 159a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 164b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 16550210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 166b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1698afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 17363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 17463f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 17663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1778afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 178c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 179c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 18399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 18499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 18599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 18699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 189a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 190a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 191a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 194c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 19913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 202a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 20499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2057e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 20896f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 20996f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 21096f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 21196f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 216dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 217dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 2363ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 2378dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 238dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 268692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 269692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 270692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 276e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 278692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 291a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2923330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 298921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 3001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 302a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 303a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 304a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 3050a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato 3060a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato const int LOGTAG_SF_STOP_BOOTANIM = 60110; 3070a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, 3080a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 318921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 319921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 322921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 323921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 325921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 326921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3295167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 3305167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const char* label) : 3310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3320a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3335167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncOnLabel(String8::format("VsyncOn-%s", label)), 3345167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden mVsyncEventLabel(String8::format("VSYNC-%s", label)), 335db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mDispSync(dispSync), 336db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallbackMutex(), 337db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallback(), 338db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mVsyncMutex(), 339db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset(phaseOffset), 340db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled(false) {} 341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 345db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3470a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis status_t err = mDispSync->addEventListener(mPhaseOffset, 348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3535167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 3615167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 363db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled = enable; 364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 367db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 371db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza virtual void setPhaseOffset(nsecs_t phaseOffset) { 372db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 373db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 374db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Normalize phaseOffset to [0, period) 375db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza auto period = mDispSync->getPeriod(); 376db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset %= period; 377db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (phaseOffset < 0) { 378db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're here, then phaseOffset is in (-period, 0). After this 379db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // operation, it will be in (0, period) 380db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset += period; 381db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 382db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset = phaseOffset; 383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're not enabled, we don't need to mess with the listeners 385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (!mEnabled) { 386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return; 387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Remove the listener with the old offset 390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza status_t err = mDispSync->removeEventListener( 391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error unregistering vsync callback: %s (%d)", 394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Add a listener with the new offset 398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza err = mDispSync->addEventListener(mPhaseOffset, 399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza static_cast<DispSync::Callback*>(this)); 400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza ALOGE("error registering vsync callback: %s (%d)", 402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 406faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 407faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 408faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 409faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 411faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 412a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 4130a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 4140a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 4155167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 4160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 420faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 422faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 4260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 4275167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 4285167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 4290a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 431db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 432db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mCallbackMutex; // Protects the following 433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 434db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 435db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mVsyncMutex; // Protects the following 436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza nsecs_t mPhaseOffset; 437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza bool mEnabled; 438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 441a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 442a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 444692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall Mutex::Autolock _l(mStateLock); 445692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 446b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 44734a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 44834a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 450f9481058101c4e2b38c74048feac383664691d03Saurabh Shah // start the EventThread 451f9481058101c4e2b38c74048feac383664691d03Saurabh Shah sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 452f9481058101c4e2b38c74048feac383664691d03Saurabh Shah vsyncPhaseOffsetNs, true, "app"); 453f9481058101c4e2b38c74048feac383664691d03Saurabh Shah mEventThread = new EventThread(vsyncSrc); 454f9481058101c4e2b38c74048feac383664691d03Saurabh Shah sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 455f9481058101c4e2b38c74048feac383664691d03Saurabh Shah sfVsyncPhaseOffsetNs, true, "sf"); 456f9481058101c4e2b38c74048feac383664691d03Saurabh Shah mSFEventThread = new EventThread(sfVsyncSrc); 457f9481058101c4e2b38c74048feac383664691d03Saurabh Shah mEventQueue.setEventThread(mSFEventThread); 458f9481058101c4e2b38c74048feac383664691d03Saurabh Shah 459b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 460b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 461b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 462b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 463b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 464875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // get a RenderEngine for the given display / config (can't fail) 46505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); 466875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 467875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 468875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 469a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 470da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 471da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 472da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 473cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 475f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 476f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // set-up the displays that are already connected 4779e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 479dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool isSecure = true; 480692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked(type); 481692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 482692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 483b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> producer; 484b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> consumer; 485b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&producer, &consumer, 486b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 487b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza 488b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, 489b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza consumer); 49019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall int32_t hwcId = allocateHwcDisplayId(type); 491f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 49219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall type, hwcId, mHwc->getFormat(hwcId), isSecure, token, 493b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza fbs, producer, 49405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 495f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 496c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 497f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 498f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 49986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGD("marking display %zu as acquired/unblanked", i); 5002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(HWC_POWER_MODE_NORMAL); 501f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 502f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 503f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 505cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 506a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // make the GLContext current so that we can create textures when creating Layers 507a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // (which may happens before we render something) 508a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 509a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 510d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 511d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 512d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 513faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // set a fake vsync period if there is no HWComposer 514faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mHwc->initCheck() != NO_ERROR) { 515faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(16666667); 516faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 517faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 51892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 51992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 5208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 52113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 52213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 52313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 524a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 525a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 5299e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ? 5303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 5313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 5323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 533a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 534a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 535a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 536a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 537a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 538a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 539875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 540875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 541a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 542a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 543875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 544875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 545a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 546a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 548d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 549582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 5502adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 551134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 552097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 5536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 554134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 555134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 55823e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa if ((configs == NULL) || (display.get() == NULL)) { 5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5627aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 5637aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 5647aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 565692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5669e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 567692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 575c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5798b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5808b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5818b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5828b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5848b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5858b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5868b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5878b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5898b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5908b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5918b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5928b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5931604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const Vector<HWComposer::DisplayConfig>& hwConfigs = 5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza getHwComposer().getConfigs(type); 5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza for (size_t c = 0; c < hwConfigs.size(); ++c) { 5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza const HWComposer::DisplayConfig& hwConfig = hwConfigs[c]; 6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float xdpi = hwConfig.xdpi; 6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float ydpi = hwConfig.ydpi; 6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 6067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 6097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 6107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 6117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 6127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 6137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6147f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 6157f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 6167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 6177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 6187f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 6197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 6207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6217f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 6227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 6237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = hw->getOrientation(); 6247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 6257f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 6267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 6277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 6291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 6307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.w = hwConfig.width; 6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.h = hwConfig.height; 6337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 6347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.fps = float(1e9 / hwConfig.refresh); 63691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; 63791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden 63891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 63991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 64091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 64191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 64291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 64391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 64491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 64591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 64691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 64791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 64891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 64991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 65091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden info.presentationDeadline = 65191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000; 6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 6557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->push_back(info); 6578b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 6588b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 6597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 6607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 661dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 66289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 66367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 66467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar if (stats == NULL) { 66567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 66667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 66767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 66867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 66967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 67067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 67167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 67267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 67367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 67467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 67624a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza sp<DisplayDevice> device(getDisplayDevice(display)); 67724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza if (device != NULL) { 67824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 67924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 68024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 6817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 682dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 6836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 6846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 6856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 6866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 6876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 6886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 6906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 6916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 6966c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 6976c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 6986c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 6996c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 7006c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 7016c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 7026c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 7036c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 7046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 7056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 7137306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 7147306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 715784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 7169ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 7177306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 7187306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (hw == NULL) { 7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 7227306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 734888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 735c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 736c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 737d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 738d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 739d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 740d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 741d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 742d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 743d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 744d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 745d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 746d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 747d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 748d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 749d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 750d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 751d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 7528aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 753bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 754bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 75699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 75799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 75899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 75999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 76099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 76199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 76299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 76399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 76499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 76599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 76699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 76799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 76899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 76999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 77099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 77199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 77299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 77399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 774c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 77599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 77699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 77799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 77899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 779c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 78099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 78199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 78299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 78399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 78499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 78599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7874f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 7884f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 7894f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 7904f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 79199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 793faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 794faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 795948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 796faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 797d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 798d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 799faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 80043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 801faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 802faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 803948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 804faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 805faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 806948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 807948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 808948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 809948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall ALOGE("resyncToHardwareVsync called when HW vsync unavailable"); 810948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 811948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 812948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 813faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const nsecs_t period = 814faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 815faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 816faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 817faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 818faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 819faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 820faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 821d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 822d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 823faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 824faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 825faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 826faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 827948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 828faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 829faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 830d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 831d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 832faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 833faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 834faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 835948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 836948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 837948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 838faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 839faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 840faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 841d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 842faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 843d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 844d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 845d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 846d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 847faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 848148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 849d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 850d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 851d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 852d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 853d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 854d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 855148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 856148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 857148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 858148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 859148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 860148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 861148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 862148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 863148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 864148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 8659e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8669e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 8679e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 868692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 869692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 8709e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 871692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 872692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 8739e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 8749e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 8759e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 8769e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 8773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 8788630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8798630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 88081cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 881faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 88281cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 8838630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 8848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 8854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 8861c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 88799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 8886b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::TRANSACTION: { 8896b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageTransaction(); 8906b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 8916b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 8926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 8936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 8946b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 8955878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 8966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 8975878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 8985878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 8995878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 9006b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 9016b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 9026b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 9036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 9046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 9056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 9066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 9076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 9084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9116b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 912e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 91487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 9156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 9164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 9176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 9206b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 9226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 9243a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 9254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 927cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 928cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 929cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 930cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 931cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 932cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 933cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 934cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 935cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 936cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 937cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 938cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 939cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 940cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 941cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 942cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 943cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 9442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 945cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 946cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 947cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 948cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 949cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 950cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 951cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 952cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 9533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 9543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 9553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 956cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 957da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 958cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 959cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 963cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 964cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 965cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 966cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 967bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 968bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 969bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 970bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 971bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 972bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 973cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 974cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 975cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 976cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 977cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 9781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 982cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 983cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 984cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 987cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 988cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 989a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 990cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 991cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 9921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 9931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 994cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 9951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian layers[i]->onPostComposition(); 996cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 9974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 998faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const HWComposer& hwc = getHwComposer(); 999faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 1000faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1001faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 1002faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1005948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1006faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1008faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1009b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 10105167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden if (kIgnorePresentFences) { 10112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1012faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1014faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1015faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 10164b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 10174b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 10184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 1019a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 10204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 10214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 10224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 10234b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 10244b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 10254b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 10264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 10274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 10284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1029b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1030b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1031b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1032b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1033b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1034b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1035b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1036b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1037b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1038b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t period = mPrimaryDispSync.getPeriod(); 1039b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t elapsedTime = currentTime - mLastSwapTime; 1040b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza size_t numPeriods = static_cast<size_t>(elapsedTime / period); 1041b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (numPeriods < NUM_BUCKETS - 1) { 1042b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[numPeriods] += elapsedTime; 1043b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 1044b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; 1045b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1046b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mTotalTime += elapsedTime; 1047b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1048b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mLastSwapTime = currentTime; 1049cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1050cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1051cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 1052cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 105352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1054cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 105587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 105687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 1057ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 10581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 105992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1060ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 1061ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 106213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Vector< sp<Layer> > layersSortedByZ; 10634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 10647e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 10657e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 10662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 10671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 1068ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 10697e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 10701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 1071ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 10721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 10731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1074ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 1075a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 1076a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 1077a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 1078a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 1079ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 1080ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 108187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 108287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 10833b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 10844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 10857e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 10867e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 10877e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 10883b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 10893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1090cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 10913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1092cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 1093028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1094b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty(); 1095b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1096b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1097b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1098b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1099b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1100b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1101b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1102b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1103b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1104b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1105b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1106b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1107b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1108b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1109b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1110b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1111b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1112b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1113b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1114b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 11157143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1116b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1117b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1118b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1119b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1120028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1121028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 112252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 112352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 112452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 1125a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 1126a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 1127a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1128a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 1129a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 1130a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1132a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 1133a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 1134a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 1135a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1136a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1137a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1139a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 11409c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { 1141a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 1142a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1143a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1144a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1145a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1146a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1147a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 1148a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 1149a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 115092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 11514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 1152e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 1153e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 1155cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 1156e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 1157a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 1158a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 1159a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 1160a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 1161a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 1162a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 1163a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1165a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 11661e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 116887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1169a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 117003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews // If possible, attempt to use the cursor overlay on each display. 117103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 117203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 117303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 117403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id >= 0) { 117503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 117603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 117703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 117803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 117903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 118003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 118103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 118203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (layer->isPotentialCursor()) { 118303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews cur->setIsCursorLayerHint(); 118403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 118503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 118603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 118703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 118803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 118903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 119052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 119152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 119238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 119338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 119438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall sp<const DisplayDevice> hw(mDisplays[dpy]); 119538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall hw->prepareFrame(hwc); 119638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 119752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1198cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 119952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 1200cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 1201cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 120252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 120392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 12044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 12052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1207cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 120802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 120902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 121002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 121102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 121587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 121652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 12174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 12184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 121952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1224841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1225b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 1226a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 1227a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 1228c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 122952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 1230ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 12312a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 12322a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 12332a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 12342a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 1235875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 12362a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 1237e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 123852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 123952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 12406da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // make the default display current because the VirtualDisplayDevice code cannot 12416da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // deal with dequeueBuffer() being called outside of the composition loop; however 12426da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // the code below can call glFlush() which is allowed (and does in some case) call 12436da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // dequeueBuffer(). 12446da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 12456da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian 124692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 12474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 124813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1249da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 125052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 1251e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1252e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 12531e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 12541e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 125552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1256d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 125752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1258cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 125952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1260d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 126152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1262ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1263e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1264e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1265a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1266a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 12676547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 12686547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 12696547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 12706547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 12716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 127487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1276841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1277841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 12787cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 12797cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 12807cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 12817cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 12827cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 12837cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1284ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1285ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1286ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1287ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1288ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1289ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1290ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1291ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1292ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1293ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 129587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1296ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1297ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1298ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1299ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1300ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 13013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 13043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 13053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 13263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1329e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 133192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 133292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1333e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 133592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 133792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 133893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 133992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 134092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 134192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 134292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 134392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 134492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1346e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 134792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 13483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 134927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 135027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 135127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 135202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1353875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 135402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 135502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 135602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 13579e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 13587adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 135902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 136092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 136192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 136292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 136392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 136492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1365e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 13663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1367097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 1368097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 13691474f8864faafebc92ff79959bb5c698bd29b704Dan Albert if (state_binder != draw_binder) { 1370e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 137193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 137293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 137393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 137402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 137502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 137602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 137793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 137893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 137993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 138093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 138193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 138292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 138393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1384db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 138593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 138693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 138793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 138893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 138900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 139000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 139100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 139200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 139300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 13944fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 139593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 139647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (state.width != draw[i].width || state.height != draw[i].height) { 139747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp->setDisplaySize(state.width, state.height); 139847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 139992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 140092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 140192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 140292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 140392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 140492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 140592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1408cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 140999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1410db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1411b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferProducer> bqProducer; 1412b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza sp<IGraphicBufferConsumer> bqConsumer; 1413b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, 1414b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza new GraphicBufferAlloc()); 1415db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 141602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall int32_t hwcDisplayId = -1; 141799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 141802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 141902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 142002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 142199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1422db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 14231f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int width = 0; 14241f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int status = state.surface->query( 14251f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_WIDTH, &width); 14261f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 14271f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query width (%d)", status); 14281f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza int height = 0; 14291f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza status = state.surface->query( 14301f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza NATIVE_WINDOW_HEIGHT, &height); 14311f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza ALOGE_IF(status != NO_ERROR, 14321f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza "Unable to query height (%d)", status); 14331f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 || 14341f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza (width <= MAX_VIRTUAL_DISPLAY_DIMENSION && 14351f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) { 14361f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza hwcDisplayId = allocateHwcDisplayId(state.type); 14371f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza } 14381f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza 1439db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface( 1440b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *mHwc, hwcDisplayId, state.surface, 1441b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqProducer, bqConsumer, state.displayName); 1442db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1443db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 144447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine producer = vds; 144599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 144699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1447cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1449cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1450cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 145102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1452cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1453cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1454b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza dispSurface = new FramebufferSurface(*mHwc, state.type, 1455b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza bqConsumer); 1456b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza producer = bqProducer; 1457cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1458cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1459cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 146099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1461cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 146219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall state.type, hwcDisplayId, 146319e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall mHwc->getFormat(hwcDisplayId), state.isSecure, 146405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall display, dispSurface, producer, 146505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1466cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1467cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 14684fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 14698dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1470cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 14711c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (state.isVirtualDisplay()) { 14721c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (hwcDisplayId >= 0) { 14731c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall mHwc->setVirtualDisplayProperties(hwcDisplayId, 14741c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getWidth(), hw->getHeight(), 14751c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getFormat()); 14761c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 14771c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } else { 14787adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 14791c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 148093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 148192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 148292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 14843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 14868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 14878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 14888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 14898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 14908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 14928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 14938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 14958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 14968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 14978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 14988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 14998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 15008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 15018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 15028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 15038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 15048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 15058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 15068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 15078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 15088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 15098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 15108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 15118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 15131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 15148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 15158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 15168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 15178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 15188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 15198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 15208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 15218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 15228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 15238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 15248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 15258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 152691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 15278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 15288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 15298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 15308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 15318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 153291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 153391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 153491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 153591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 153691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 153791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 153891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 153991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 15408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 154191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 15428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 15438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 15448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 15458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 15463559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 15473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 15483559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 15511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 15523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 15533559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 15543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 15553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 15563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 15573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 15583559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 15593559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 15603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 15611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 15623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 15631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 15643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 15653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 15663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 15673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 15683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 15691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 15701501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 15711501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 15721501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 15730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 157803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 157903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 158003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 158103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 158203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 158303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 158403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer& hwc(getHwComposer()); 158503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 158603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews sp<const DisplayDevice> hw(mDisplays[dpy]); 158703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const int32_t id = hw->getHwcDisplayId(); 158803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (id < 0) { 158903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 159003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 159103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const Vector< sp<Layer> >& currentLayers( 159203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hw->getVisibleLayersSortedByZ()); 159303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const size_t count = currentLayers.size(); 159403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews HWComposer::LayerListIterator cur = hwc.begin(id); 159503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const HWComposer::LayerListIterator end = hwc.end(id); 159603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 159703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) { 159803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 159903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 160003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews const sp<Layer>& layer(currentLayers[i]); 160103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews Rect cursorPos = layer->getPosition(hw); 160203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews hwc.setCursorPositionAsync(id, cursorPos); 160303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews break; 160403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 160503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 16064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 16074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 16084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 16094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 16104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 16114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 16124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 16134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 16144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 16164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 16184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 16194b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 16204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 16214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 16224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 16232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 16242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 16254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 162987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 163087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1632841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1633841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 16451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 164701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 164887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 164987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 165087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1670a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1671a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1672a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1673a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1674a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1675a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1676a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1677a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1678a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1679a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1682da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 16834125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 16845219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian Rect bounds(s.transform.transform(layer->computeBounds())); 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 16894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 16904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 16914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 16924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 16932ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = tr.transform(s.activeTransparentRegion); 16944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 16954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 16964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1697a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 16984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 16994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 17002ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = s.activeTransparentRegion; 17014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 17054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 17284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1731a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1732ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1737ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1738ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1739ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1740ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1741ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1742a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1743ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 17444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 17454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1746ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1747ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 175287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1754ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 17568b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1757a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1760a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1761a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 176487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 176787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 176887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 176992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 17704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 17714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 17724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 177392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 177492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 177587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 177687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 17776b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 17794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 178099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 17814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 17821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 17836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 178451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 178551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 178651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 178751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 178851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 178951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 179051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 179151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 179251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 179351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 179451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Vector<Layer*> layersWithQueuedFrames; 179551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layers.size(); i<count ; i++) { 17961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 17976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 17986b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 17996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 18006b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza layersWithQueuedFrames.push_back(layer.get()); 1801ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1802ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 18036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 1804ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 1805ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 18066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 180751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner } 180851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { 180951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner Layer* layer = layersWithQueuedFrames[i]; 181087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 1811ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 18121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 181387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 18144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 18154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 18163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 18176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 18186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 18196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 18206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 18216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (frameQueued && layersWithQueuedFrames.empty()) { 18226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 18236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 18246b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 18256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 18266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return !layersWithQueuedFrames.empty(); 1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1829ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1830ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1831ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1832ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1833ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 183499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 183687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 18387143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 18397143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 18407143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 18417143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 18427143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 18437143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 18447143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 18457143316af216fa92c31a60d4407b707637382da1Dan Stoza } 18467143316af216fa92c31a60d4407b707637382da1Dan Stoza 184787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 184887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1849b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 18504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 18530f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 185429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 185529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 185629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 18574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 18590f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 186029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1861df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 186295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 18630f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 18644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 186629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 18674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 18684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { 18733f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if (!doComposeSurfaces(hw, dirtyRegion)) return; 1874ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 1875ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian RenderEngine& engine(getRenderEngine()); 18769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mat4 colorMatrix = mColorMatrix; 18779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDaltonize) { 18789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette colorMatrix = colorMatrix * mDaltonizer(); 18799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 1880f008799d3753e52c10849824ff8146985ea66284Dan Stoza mat4 oldMatrix = engine.setupColorTransform(colorMatrix); 1881ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1882f008799d3753e52c10849824ff8146985ea66284Dan Stoza engine.setupColorTransform(oldMatrix); 1883ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18859c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 18864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1887da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1888da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1889da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18923f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 18943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 18968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 18971e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 18981e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1900d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall bool hasGlesComposition = hwc.hasGlesComposition(id); 190185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1902875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) { 1903c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1904c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 19053f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 19063f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { 19073f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 19083f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 19093f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 1910c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1911a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1912a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 191385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1914e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1915b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1916b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1917b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 19183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 1919b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 19203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 0); 1921b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1922766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1923766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1924766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1925766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1926766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1927766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1928766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1929766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1930766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1931766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1932766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1933766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1934766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1935766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1936b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 193787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1938b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 193955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1940b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1941a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1942f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1943766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1944766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1945f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1946f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1947f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1948766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1949f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1950f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1951f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1952f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 19533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1954f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 19553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian const uint32_t height = hw->getHeight(); 19563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setScissor(scissor.left, height - scissor.bottom, 19573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 1958f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1959f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 196085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 19614b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 196285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 196385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 196485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 19654b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 196613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); 196785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 196885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 196985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 197085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 197185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 197213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 197485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 197585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 197603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews case HWC_CURSOR_OVERLAY: 197785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 1978ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 197985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 198085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 19814125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden && layer->isOpaque(state) && (state.alpha == 0xFF) 198285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1983cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1984cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 198785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 198885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 198985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1990cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 199185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1992a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1993da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1994da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1995da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 199686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i); 1997da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1998da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1999cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 2000a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 200185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 200285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 200385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 200485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 200585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 200613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 200785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 200885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 200985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 201085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 201185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 20124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 20134b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 2014f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 2015f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 20163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableScissor(); 20173f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 2018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 202155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 20223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 20233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 2024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20267d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 2027ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 20286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 202913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 20301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 20317d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 20327d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 20337d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 20347d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) { 20357d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 20367d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 20377d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mCurrentState.layersSortedByZ.add(lbc); 20387d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); 20397d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 20407d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 204196f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 2042ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 20434f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 20447d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 204596f0819f81293076e652792794a961543e6750d7Mathias Agopian} 204696f0819f81293076e652792794a961543e6750d7Mathias Agopian 20473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { 204896f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 204913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 2050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 20516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mLayersPendingRemoval.push(layer); 2052076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 20536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian setTransactionFlags(eTransactionNeeded); 2054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 20563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 2057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2059c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) { 2060dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 2061dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 2062dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 20633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 2065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 2068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 2069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 207099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 2071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20758b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 20768b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 20778b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 20788b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 20798b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 20807c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 2081698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 208228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 20842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 20852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 20862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 20872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 20887c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 20892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 20902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 20917c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 20927c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 20937c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 20942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 20952d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 20962d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20972d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 20992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 2104b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 2105b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 2107698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 2108698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 2109d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 2110d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 2111d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 2112d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 2113d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 2114d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 2115d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 2116d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 2117097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(s.client); 2118d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 2119d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 2120d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 2121d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 2122d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 2123d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2124d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2125d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 2126698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 2127386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 212828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 2129386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 213028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 2131698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 2132386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 2133386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 2134386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 21352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 21362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 21372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 21382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 2139386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 21402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 2141386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 2142386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 2143386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 2144386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 21452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 21462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 2147386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 2148386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 2149cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2153e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 2154e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 21559a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 21569a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 21579a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 21589a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 2159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 21609a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 21613ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 2162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 2164097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 2165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 2166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 2170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 2171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 2172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 217500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 2176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 2177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 2178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 2181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 2182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 2185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 2186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 2187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 218947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 219047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 219147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 219247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 219347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 219447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 219547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 219647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 219747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 219847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 2199e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2200e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2201e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2202e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2203e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 2204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 2205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 2206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 2207e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 220813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 2209e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 2210e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 2211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 2212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 2213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 2216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 2219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 2227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 2228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 2232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 2233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 2236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 2237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 2240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 2241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2243231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza if (what & layer_state_t::eFlagsChanged) { 2244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 2245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 2248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 2249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 2250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 2252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 2253e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 2254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 2255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 2256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 2257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 2258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 2259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 2260e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2262e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 2263e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 2264e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 2265e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 22664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 22670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 22680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 22694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 22704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 2271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 22736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 2274921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 22756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 22764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 22776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 22788b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 22794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 22804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 22824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 22833165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 22843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 22854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 22864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 22874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 22893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 22904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 22914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 22924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 22934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 22944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 22954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 2296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 23007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 2301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 23027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 23037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza result = addClientLayer(client, *handle, *gbp, layer); 23047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 23057d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 23067d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 23077d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 23087d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 23094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 23134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 23144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 231792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 2320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 23238f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 2324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 23284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 23294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 23304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2331b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 23334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 23344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 23354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 2336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 23394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 23404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 2341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 23424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 23434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 2344b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza *gbp = (*outLayer)->getProducer(); 23454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 2346118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2347118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2348ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 23499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 23506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 23516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 23526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 23536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 23546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 23556710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 23566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 23579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 23589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 23599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 23609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 236113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 23636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 23646710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 2365ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 236613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> l(layer.promote()); 2367ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 23686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 2369e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2370ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2371ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2372ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2375b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2376b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 237713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 237801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 237913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 238013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 238113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 238201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 238301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2384692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 238501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 238613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 23874c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 23884c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 238947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 239047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 239113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 239213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 23932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL); 23946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 23956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const nsecs_t period = 23966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 23976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 239813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 239913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 240013a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 240113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 240213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 240313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 240413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 240513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 240613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 240713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 240813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 240913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 241013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 241113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 241213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 241313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 24142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 24152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mode) { 24162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 24172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 24182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 24192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 242013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 24212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 24222c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 2423c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2424c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2425c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 24262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 24272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 24282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 24292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 24302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 2431c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 24322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 24332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2434c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2436c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2437948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2438c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24402c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 2441b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 24422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani repaintEverything(); 24432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 2444c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2445948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2446948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2447cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2449cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2450c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 24512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 24522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 24532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 24542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 24552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 2456b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 24602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 2461db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2462db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 24632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 2464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 24652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 24662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 24672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 2468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 24692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2470db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 24712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 24727306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 24739e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 24742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 24752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 2476db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 24772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mFlinger.setPowerModeInternal(hw, mMode); 2478db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 24822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 2483db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 249199b49840d309727678b77403d6cc9f920111623fMathias Agopian 2492bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2493bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2494bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2495bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2496bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 249774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2498bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2500fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 25019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 25029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 2503fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 2504fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 25059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 2506fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 2507fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 2508fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 25099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 25109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 251182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 251282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 251325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 251425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 251525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 251625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 251725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 251874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 251935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 252025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 252125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 252225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 252325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 252482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 252574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 252635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 252782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 252825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 252925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 253025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 253125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 253274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 253335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 253425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2535c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 2536c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 2537c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 2538c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 2539c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 2540c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 2541c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 2542b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 2543b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 2544b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 2545b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 2546b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2547b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 2548b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 2549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 255182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 255274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 255382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 255448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 255582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 255682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 255748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 255882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 255982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 256082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 256182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 256248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 2563c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 2564c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 256525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 256625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 256725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 256825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 256913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 257074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 257125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 257225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 257325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 257574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 257682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 257782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 257982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 258182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 258248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 25834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const nsecs_t period = 25844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 258586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 25864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 25874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 2588d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 25894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 25904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 25914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 25924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 259313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 25944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 2595d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 25964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 259782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 259882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 259982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2600ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 260125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2602c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 260325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 260425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 260525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 260625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 260725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 260825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 260925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 261025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 261125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 261225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 261313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 261425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 2615d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 261625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 261725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 26184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 2619d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 262025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 262125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 26226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 26236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 26246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 26256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 26266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 26276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 26286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 26296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 26306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 26316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 26326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 26336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 26346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 26354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 26364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 26374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 26384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 26394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 26404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 26414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 26424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 26434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 26444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 26454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 26464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 26474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 26484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 26494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 26504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 26514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 2652b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 2653b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 2654b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 2655b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { 2656b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[b] / 1e9; 2657b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2658b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[b]) / mTotalTime; 2659b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 2660b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 2661b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 2662b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; 2663b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 2664b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; 2665b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 2666b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza NUM_BUCKETS - 1, bucketTimeSec, percent); 2667b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 2668b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 266974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 267074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 267182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 26723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 26733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 26743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 26753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 26763e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 26773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 26783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 26793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 26803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 268182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 268282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 268382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 268482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 268582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 268682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2687bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 268882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 26894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 26904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 26913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 26923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 26934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 26943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 26954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 26964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 26974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 26984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 26994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 27003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2701ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 27023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2703ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2704ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2705ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 270641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 270741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 270841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 270924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " 271024cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall "present offset %d ns (refresh %" PRId64 " ns)", 271141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS, 271241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY)); 271341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 271441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 2715b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 2716b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 2717b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 2718b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 2719b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 27204803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 272182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 272282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 272382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 272482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 27253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 272686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Visible layers (count = %zu)\n", count); 27273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 272882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 272913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 27303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 273182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2732bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 273382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 27345f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 27355f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 27365f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 27373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 273886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 27393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 27405f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 27415f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 274274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 27435f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 27445f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 27455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 274682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 274782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 27481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 27493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 275074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 27513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 27521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2753888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 27544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2755ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 27563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 27573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 27583e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 27593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 27603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 2761ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 2762ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 2763875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 27649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 27654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 27672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->getOrientation(), hw->isDisplayOn()); 276874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 276982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 277082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2771c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 277282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 277382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 2774ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 2775ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 2776ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 277782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 277882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2779c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2780b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2781b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2782ed985574148a938bc3af24442eead313cc62521cMathias Agopian hwc.getDpiY(HWC_DISPLAY_PRIMARY), 2783ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 278482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 278574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 278682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 278782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 278874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 278982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 279082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 279182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 279282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 279382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 279474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 279582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 279682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 279782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 279882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 27993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 280074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 28013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 280274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" h/w composer %s and %s\n", 280382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 28049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette (mDebugDisableHWC || mDebugRegion || mDaltonize 28059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette || mHasColorMatrix) ? "disabled" : "enabled"); 280674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 280782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 280882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 280982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 281082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 281182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 281282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 281513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 281648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 2817db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 281848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 281948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 282048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 282148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 282248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 282348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 282448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 282548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 282648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 282748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 282848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 282948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 283048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 2831cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2832cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 283363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 283463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 283563f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 283663f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 283763f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 283863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 283963f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 284063f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 284163f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 284224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 284363f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 284463f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 284563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 284663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 284763f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 284863f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 284963f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 285063f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2856041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 2857698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 2859d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 2860d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 28612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 2862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2866a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 28673bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 286899b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2869e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2870375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2871375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 28731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 28741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 28761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 28771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 28781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 28791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 28801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 288199b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 288299b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2883e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 28841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 28851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 28861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 28871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 28901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2893b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 289499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2895375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2896375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2897375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2898e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2899375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 290401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 290535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 291053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 291153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 291453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2915cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2916cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2917cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2918e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2922cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 29244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 29254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 29264d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 29274d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 292853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 292953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 293053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 293153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 293253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 293353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2934a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2935a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2936a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2937a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2938a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2939a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 294101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2944b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 294512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 29494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 29504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2951ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 2952ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2953ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 2954ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 2955ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 2956ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 2957ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1: mDaltonizer.setType(Daltonizer::protanomaly); break; 2958ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break; 2959ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 3: mDaltonizer.setType(Daltonizer::tritanomaly); break; 2960ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2961ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 2962ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::correction); 2963ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 2964ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::simulation); 2965ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2966ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonize = n > 0; 2967ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 2968ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 29699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 29709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 29719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 29729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 29739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 29749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix = n ? 1 : 0; 29759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 29769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 29779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 29789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 2979794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 2980794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t j = 0; j < 4; j++) { 2981794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette mColorMatrix[i][j] = data.readFloat(); 2982794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette } 29839c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 29849c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 29859c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 29869c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 29879c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 29889c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 29899c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 2990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2991f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 2992f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 2993f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 2994645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 2995645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 2996f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 2997f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 2998ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 2999ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 3000ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 3001ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 3002ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 3003db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 3004db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3005db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3006db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3007db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3008db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 3009db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 3010db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 3011db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 3012db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 3013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 3016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 301853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 301987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 302099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 302153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 302253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 302359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 30242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 30252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 302659119e658a12279e8fff508f8773843de2d90917Mathias Agopian 30272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 30282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 30292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 3030b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they 3031b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be 3032b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the 3033b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests. 30342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 30352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 3036b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall /* Parts of GraphicProducerWrapper are run on two different threads, 3037b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * communicating by sending messages via Looper but also by shared member 3038b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * data. Coherence maintenance is subtle and in places implicit (ugh). 3039b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3040b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Don't rely on Looper's sendMessage/handleMessage providing 3041b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * release/acquire semantics for any data not actually in the Message. 3042b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Data going from surfaceflinger to binder threads needs to be 3043b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * synchronized explicitly. 3044b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * 3045b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Barrier open/wait do provide release/acquire semantics. This provides 3046b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * implicit synchronization for data coming back from binder to 3047b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * surfaceflinger threads. 3048b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall */ 3049b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 30502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 30512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 30522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 30532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 30542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 3055b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall Barrier barrier; 30562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 30572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 30582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 30592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 30612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 30622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 30632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 30642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3066b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * Called on surfaceflinger thread. This is called by our "fake" 3067b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * BpGraphicBufferProducer. We package the data and reply Parcel and 3068b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * forward them to the binder thread. 30692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 30702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 3071c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza const Parcel& data, Parcel* reply, uint32_t /* flags */) { 30722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 30732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 30742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 30752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 3076b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // if we've exited, we run the message synchronously right here. 3077b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // note (JH): as far as I can tell from looking at the code, this 3078b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // never actually happens. if it does, i'm not sure if it happens 3079b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // on the surfaceflinger or binder thread. 30802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 30812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 30822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 3083b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent stores to this->{code, data, reply} from being 3084b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // reordered later than the construction of Message. 3085b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 30862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 30872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 30882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 3089c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng return result; 30902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 30912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 30922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 3093b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * here we run on the binder thread. All we've got to do is 30942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 30952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 30962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 3097b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall int what = message.what; 3098b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Prevent reads below from happening before the read from Message 3099b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_acquire); 3100b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall if (what == MSG_API_CALL) { 3101097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen result = IInterface::asBinder(impl)->transact(code, data[0], reply); 31022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 3103b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall } else if (what == MSG_EXIT) { 31042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 31052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 31062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 31072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 31082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 3109b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) 3110b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall : impl(impl), 3111b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall looper(new Looper(true)), 3112b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitPending(false), 3113b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall exitRequested(false) 3114b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall {} 3115b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall 3116b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Binder thread 31172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 31182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 31192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 31202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 31212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 31222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 31232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 3124b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Client thread 31252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 3126aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 31272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 3128b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // Ensure this->result is visible to the binder thread before it 3129b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall // handles the message. 3130b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall atomic_thread_fence(memory_order_release); 31312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 31322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 31332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 31342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 31352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 31362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 31372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3138c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3139c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3140c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { 31412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 31422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 31432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 31442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 31452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 31462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 31472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 31485ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 31495ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 31505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 3151097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (!IInterface::asBinder(producer)->localBinder()) { 31525ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian Mutex::Autolock _l(mStateLock); 31535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 31545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (hw->getSecureLayerVisible()) { 31555ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 31565ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian return PERMISSION_DENIED; 31575ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 31585ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 31595ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 3160c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews // Convert to surfaceflinger's internal rotation type. 3161c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotationFlags; 3162c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews switch (rotation) { 3163c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotateNone: 3164c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3165c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3166c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate90: 3167c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_90; 3168c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3169c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate180: 3170c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_180; 3171c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3172c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews case ISurfaceComposer::eRotate270: 3173c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_270; 3174c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3175c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews default: 3176c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotationFlags = Transform::ROT_0; 3177c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); 3178c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews break; 3179c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews } 3180c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews 31812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 31822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 31832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 31842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 3185c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop; 31862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 31872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 3188c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza bool useIdentityTransform; 3189c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews Transform::orientation_flags rotation; 31902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 31912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 31922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 31932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 31942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3195c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3196c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3197c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 31982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 3199c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight), 32002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 3201c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza useIdentityTransform(useIdentityTransform), 3202c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews rotation(rotation), 32032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian result(PERMISSION_DENIED) 32042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 32052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 32062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 32072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 32082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 32092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 32102a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 32112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 3212c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza result = flinger->captureScreenImplLocked(hw, producer, 3213c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3214c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3215097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result); 32162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 32172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 32182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 32192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 32209eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // make sure to process transactions before screenshots -- a transaction 32219eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // might already be pending but scheduled for VSYNC; this guarantees we 32229eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // will handle it before the screenshot. When VSYNC finally arrives 32239eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // the scheduled transaction will be a no-op. If no transactions are 32249eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // scheduled at this time, this will end-up being a no-op as well. 32259eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian mEventQueue.invalidateTransactionNow(); 32269eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian 32272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 32282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 32292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 32302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 32312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 32322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 32332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 32342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 32352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 3236c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 3237c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotationFlags); 32382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 32392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 32402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 32412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 32422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 32432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 3244118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3245118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3246180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3247180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 3248180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 3249c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3250180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 3251c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation) 3252180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 3253180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 32543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 3255180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3256180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 325789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_w = hw->getWidth(); 325889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const int32_t hw_h = hw->getHeight(); 325989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe const bool filtering = static_cast<int32_t>(reqWidth) != hw_w || 32600e7497957a029fd123b429388d84bba2930fddefChristopher Ferris static_cast<int32_t>(reqHeight) != hw_h; 3261180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3262c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 3263c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || 3264c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza !sourceCrop.isValid()) { 3265c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 3266c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setRightBottom(Point(hw_w, hw_h)); 3267c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3268c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3269c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 3270c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 3271c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 3272c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3273be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.right > hw_w) { 3274be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w); 3275c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3276c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 3277c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 3278c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3279be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza if (sourceCrop.bottom > hw_h) { 3280be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h); 3281c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 3282c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 3283180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 32843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 3285180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3286180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 3287c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews engine.setViewportAndProjection( 3288c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation); 32893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 3290180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3291180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 32923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 3293180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3294180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3295180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 3296180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3297180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 32981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3299180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 3300180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 3301180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 3302180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 3303c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza layer->draw(hw, useIdentityTransform); 3304180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 3305180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3306180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3307180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3308180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3309180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3310180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // compositionComplete is needed for older driver 3311180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian hw->compositionComplete(); 3312931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 3313180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 3314180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3315180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 33162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 33172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 33182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 3319c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 3320c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza uint32_t minLayerZ, uint32_t maxLayerZ, 3321c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews bool useIdentityTransform, Transform::orientation_flags rotation) 332274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 3323fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 3324fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 3325180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 33263502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_w = hw->getWidth(); 33273502416204d9dbd905012ee586d8bd145323809fDan Stoza uint32_t hw_h = hw->getHeight(); 33283502416204d9dbd905012ee586d8bd145323809fDan Stoza 33293502416204d9dbd905012ee586d8bd145323809fDan Stoza if (rotation & Transform::ROT_90) { 33303502416204d9dbd905012ee586d8bd145323809fDan Stoza std::swap(hw_w, hw_h); 33313502416204d9dbd905012ee586d8bd145323809fDan Stoza } 3332180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3333180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 3334180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 3335180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 3336180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 3337180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 3338180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 3339180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 3340180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 3341180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 33420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 33430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 334483cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 33450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 334674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 33475a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 33485a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine if (result == NO_ERROR) { 33493ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 33503ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 33512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 33520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 33530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 33544ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 33550aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 33560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 33572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 33580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 33590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 33600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 33610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 33620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 33630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 33640aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 3365866399093f9f60e7305f291e688abb456bace710Riley Andrews int syncFd = -1; 33660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 33670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 33680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 33690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 33700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 33713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 33723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 33733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 33743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 33750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 33760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 33770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 33780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 3379c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews renderScreenImplLocked( 3380c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true, 3381c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews useIdentityTransform, rotation); 3382d555684cb36dfb959694db76962e570184f98838Mathias Agopian 3383866399093f9f60e7305f291e688abb456bace710Riley Andrews // Attempt to create a sync khr object that can produce a sync point. If that 3384866399093f9f60e7305f291e688abb456bace710Riley Andrews // isn't available, create a non-dupable sync object in the fallback path and 3385866399093f9f60e7305f291e688abb456bace710Riley Andrews // wait on it directly. 3386866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLSyncKHR sync; 3387866399093f9f60e7305f291e688abb456bace710Riley Andrews if (!DEBUG_SCREENSHOTS) { 3388866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 33899707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews // native fence fd will not be populated until flush() is done. 33909707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews getRenderEngine().flush(); 3391866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3392866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = EGL_NO_SYNC_KHR; 3393866399093f9f60e7305f291e688abb456bace710Riley Andrews } 33942d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 3395866399093f9f60e7305f291e688abb456bace710Riley Andrews // get the sync fd 3396866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync); 3397866399093f9f60e7305f291e688abb456bace710Riley Andrews if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3398866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: failed to dup sync khr object"); 3399866399093f9f60e7305f291e688abb456bace710Riley Andrews syncFd = -1; 3400866399093f9f60e7305f291e688abb456bace710Riley Andrews } 34012d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 3402866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3403866399093f9f60e7305f291e688abb456bace710Riley Andrews // fallback path 3404866399093f9f60e7305f291e688abb456bace710Riley Andrews sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 3405866399093f9f60e7305f291e688abb456bace710Riley Andrews if (sync != EGL_NO_SYNC_KHR) { 3406866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 3407866399093f9f60e7305f291e688abb456bace710Riley Andrews EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 3408866399093f9f60e7305f291e688abb456bace710Riley Andrews EGLint eglErr = eglGetError(); 3409866399093f9f60e7305f291e688abb456bace710Riley Andrews if (result == EGL_TIMEOUT_EXPIRED_KHR) { 3410866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: fence wait timed out"); 3411866399093f9f60e7305f291e688abb456bace710Riley Andrews } else { 3412866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW_IF(eglErr != EGL_SUCCESS, 3413866399093f9f60e7305f291e688abb456bace710Riley Andrews "captureScreen: error waiting on EGL fence: %#x", eglErr); 3414866399093f9f60e7305f291e688abb456bace710Riley Andrews } 3415866399093f9f60e7305f291e688abb456bace710Riley Andrews eglDestroySyncKHR(mEGLDisplay, sync); 34162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 3417866399093f9f60e7305f291e688abb456bace710Riley Andrews ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 34182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 34192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 3420d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 3421d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 3422d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 3423d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 3424d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 3425d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 3426d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 3427d555684cb36dfb959694db76962e570184f98838Mathias Agopian 34280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 34290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 34300aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 34310aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 34320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 34330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 34340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 34350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 343674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 3437afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall // queueBuffer takes ownership of syncFd 34385a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine result = window->queueBuffer(window, buffer, syncFd); 343974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 34400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 34410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 344274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 34430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 344474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 344574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 344674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 344774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 344874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 3449d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 3450d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 3451fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 3452d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 3453d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 3454d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 3455fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 3456fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3457fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3458fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 3459fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 3460fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 3461fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 3462fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 3463fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 3464fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 3465fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 3466fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 3467fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 3468fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 346986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", 3470fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 3471fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 3472fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 3473fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3474fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 3475fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 3476fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 34771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 34781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 3479921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 3480921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3481921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3482921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 348313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 3484921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3485921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3486921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 3487921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 3488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3489be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 349013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 349113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 3492be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 34931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 34941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3495be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3496be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3497be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 34981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 34991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3500be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3501be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3502be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3503be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3504921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3505921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3506921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3507921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 35083ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 350947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) { 3510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 35123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 351347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) { 3514da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3515da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3516b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 35177303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3518b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 351996f0819f81293076e652792794a961543e6750d7Mathias Agopian 3520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 35213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 35223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 35233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 35243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 35253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 35263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 35273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 35283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 35293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3530