SurfaceFlinger.cpp revision 7143316af216fa92c31a60d4407b707637382da1
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> 24921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 31c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 327303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h> 3399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 35c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 36c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 37921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h> 381a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 41e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 42392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h> 43921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 44921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 47d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 48cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 521c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 55ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 6090ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 610f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h" 62faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 63d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 64d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h" 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 70a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 73ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 74ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 75875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 77875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 80fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 81fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 82fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 86ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 87ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 89faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 90faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This works around the lack of support for the sync framework on some 91faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// devices. 92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK 93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const bool runningWithoutSyncFramework = true; 94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#else 95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const bool runningWithoutSyncFramework = false; 96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#endif 97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event 99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer. The software vsync 100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each 101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame. 102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application 104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window 105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed. This value may be either positive (after the HW vsync) 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync). Setting it to 0 will result in a 107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger 108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync. Setting it to a positive number will 109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being: 110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) 112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// 113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications 114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time. When this happens 115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations 116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup. Therefore, this latency should be tuned somewhat 117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made). 118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS; 119faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs. 1210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS; 1220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12599b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 12699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 12799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 12899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 12999b49840d309727678b77403d6cc9f920111623fMathias Agopian 13099b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 13199b49840d309727678b77403d6cc9f920111623fMathias Agopian 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger() 1334f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian : BnSurfaceComposer(), 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 1352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 1362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 137076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 13852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 139875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine(NULL), 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 142a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian mHwWorkListDirty(false), 1434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 1458afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 14673d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 147a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 1509795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 1519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 152ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 153faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 154948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 1559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mDaltonize(false), 1569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix(false) 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 158a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("SurfaceFlinger is starting"); 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 1628afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 163b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 16450210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 165b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 1688afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 1698afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 17263f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 17363f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 17463f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 1768afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 177c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 178c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 18299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 18399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.init(this); 18499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 18599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 188a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 189a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 190a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian eglTerminate(display); 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 19713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 19813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 19999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 201a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 20299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2047e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20696f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<ISurfaceComposerClient> bclient; 20796f0819f81293076e652792794a961543e6750d7Mathias Agopian sp<Client> client(new Client(this)); 20896f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 20996f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 21096f0819f81293076e652792794a961543e6750d7Mathias Agopian bclient = client; 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return bclient; 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 215dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 216dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian DisplayToken(const sp<SurfaceFlinger>& flinger) 228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 2353ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 2368dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 237dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info.isSecure = secure; 238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { 263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall ALOGW_IF(mBuiltinDisplays[type], 264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall "Overwriting display token for display type %d", type); 265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type] = new BBinder(); 266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall DisplayDeviceState info(type); 267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall // All non-virtual displays are currently considered secure. 268692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall info.isSecure = true; 269692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.add(mBuiltinDisplays[type], info); 270692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall} 271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 2739e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return NULL; 276e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 277692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 2809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{ 2829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 2839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis return gba; 2849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis} 285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 290a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 2913330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBootFinished = true; 2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 297921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 2981f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 2991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 3001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 301a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 302a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 303a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 3083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine; 3093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) 3123f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian : engine(engine), texture(texture) { 313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 3153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 318921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 3193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 320921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 322faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback { 323faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 3240a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) : 3250a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 3260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mPhaseOffset(phaseOffset), 3270a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 3280a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mDispSync(dispSync) {} 329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual ~DispSyncSource() {} 331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setVSyncEnabled(bool enable) { 333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // Do NOT lock the mutex here so as to avoid any mutex ordering issues 334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // with locking it in the onDispSyncEvent callback. 335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 3360a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis status_t err = mDispSync->addEventListener(mPhaseOffset, 337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_INT("VsyncOn", 1); 343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_INT("VsyncOn", 0); 351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void setCallback(const sp<VSyncSource::Callback>& callback) { 355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> callback; 362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock lock(mMutex); 364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 365a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 3670a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 3680a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis ATRACE_INT("VSYNC", mValue); 3690a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (callback != NULL) { 373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 3790a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const nsecs_t mPhaseOffset; 3800a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 3810a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<VSyncSource::Callback> mCallback; 384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex mMutex; 385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 391b65f32ebe2c86869b07ac1c986660dfb2187b7d3Jesse Hall status_t err; 392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall Mutex::Autolock _l(mStateLock); 393692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // initialize EGL for the default display 39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 39634a09ba1efd706323a15633da5044b352988eb5fJesse Hall eglInitialize(mEGLDisplay, NULL, NULL); 397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // Initialize the H/W composer object. There may or may not be an 399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden // actual hardware composer underneath. 400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden mHwc = new HWComposer(this, 401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden *static_cast<HWComposer::EventHandler *>(this)); 402b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 403875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // get a RenderEngine for the given display / config (can't fail) 40405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); 405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // retrieve the EGL context that was selected/created 407875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = mRenderEngine->getEGLContext(); 408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian "couldn't create EGLContext"); 411da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // initialize our non-virtual displays 4139e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 415f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // set-up the displays that are already connected 4169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 418dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool isSecure = true; 419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked(type); 420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall wp<IBinder> token = mBuiltinDisplays[i]; 421692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall 422db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc()); 423db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq); 42419e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall int32_t hwcId = allocateHwcDisplayId(type); 425f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 42619e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall type, hwcId, mHwc->getFormat(hwcId), isSecure, token, 427db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian fbs, bq, 42805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 429f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian if (i > DisplayDevice::DISPLAY_PRIMARY) { 430c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: currently we don't get blank/unblank requests 431f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // for displays other than the main display, so we always 432f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian // assume a connected display is unblanked. 433c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("marking display %d as acquired/unblanked", i); 434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian hw->acquireScreen(); 435f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian mDisplays.add(token, hw); 437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian } 438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 439cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 440a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // make the GLContext current so that we can create textures when creating Layers 441a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian // (which may happens before we render something) 442a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 443a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian 444028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian // start the EventThread 4450a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4460a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis vsyncPhaseOffsetNs, true); 447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mEventThread = new EventThread(vsyncSrc); 4480a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, 4490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis sfVsyncPhaseOffsetNs, false); 4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mSFEventThread = new EventThread(sfVsyncSrc); 4510a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mEventQueue.setEventThread(mSFEventThread); 452028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian 453d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread = new EventControlThread(this); 454d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); 455d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 456faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis // set a fake vsync period if there is no HWComposer 457faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mHwc->initCheck() != NO_ERROR) { 458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(16666667); 459faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 460faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 46192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 46292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 4638630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 46413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 46513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 46613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 467a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian // start boot animation 468a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4713ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 4729e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ? 4733ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian type : mHwc->allocateDisplayId(); 4743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 4753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 476a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 477a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // start boot animation 478a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "0"); 479a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("ctl.start", "bootanim"); 480a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 482875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 483875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxTextureSize(); 484a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 485a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 486875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mRenderEngine->getMaxViewportDims(); 488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 491d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 492582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 4932adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 494134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 4952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder()); 4966710604286401d4205c27235a252dd0e5008cc08Mathias Agopian return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; 497134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 4999d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brownstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { 500692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 5019e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 5031604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 5041604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 5051604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5061604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5071604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5081604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 5091604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 510c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 5118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian const HWComposer& hwc(getHwComposer()); 5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float xdpi = hwc.getDpiX(type); 5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float ydpi = hwc.getDpiY(type); 5158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 5178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 5188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 5198b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian if (property_get(propName, property, NULL) > 0) { 5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 5321604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5331604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type == DisplayDevice::DISPLAY_PRIMARY) { 5341604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // The density of the device is provided by a build property 5351604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian float density = Density::getBuildDensity() / 160.0f; 5361604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (density == 0) { 5371604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // the build doesn't provide a density -- this is wrong! 5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // use xdpi instead 5391604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian ALOGE("ro.sf.lcd_density must be defined as a build property"); 5401604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density = xdpi / 160.0f; 5411604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5421604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (Density::getEmuDensity()) { 5431604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // if "qemu.sf.lcd_density" is specified, it overrides everything 5441604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian xdpi = ydpi = density = Density::getEmuDensity(); 5451604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian density /= 160.0f; 5461604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 5471604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = density; 5481604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 5491604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: this needs to go away (currently needed only by webkit) 5501604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 5511604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = hw->getOrientation(); 5521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } else { 5531604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian // TODO: where should this value come from? 5541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian static const int TV_DENSITY = 213; 5551604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->density = TV_DENSITY / 160.0f; 5561604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->orientation = 0; 5578b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 5588b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 5591604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->w = hwc.getWidth(type); 5601604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->h = hwc.getHeight(type); 5618b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->xdpi = xdpi; 5628b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian info->ydpi = ydpi; 5631604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian info->fps = float(1e9 / hwc.getRefreshPeriod(type)); 564dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 565dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis // All non-virtual displays are currently considered secure. 566dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis info->secure = true; 567dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 568888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 569c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 570c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 571d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 572d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 573d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 5748aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian return mEventThread->createEventConnection(); 575bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 576bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 57899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 57999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 58099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.waitMessage(); 58199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 58299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 58399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 58499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 58599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 58699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 58799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 58899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.invalidate(); 58999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 59199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 59299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian mEventQueue.refresh(); 59399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 59599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 59699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 59799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return mEventQueue.postMessage(msg, reltime); 59899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 59999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 60099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 60199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian nsecs_t reltime, uint32_t flags) { 60299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian status_t res = mEventQueue.postMessage(msg, reltime); 60399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 60499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 60599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 60699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 60799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6094f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 6104f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 6114f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 6124f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 61399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 615faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 616faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 617948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 618faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 619d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 620d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 621faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 62243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 623faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 624faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 625948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 626faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 627faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 628948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 629948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 630948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 631948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall ALOGE("resyncToHardwareVsync called when HW vsync unavailable"); 632948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 633948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 634948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 635faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const nsecs_t period = 636faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 637faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 638faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 639faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 640faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 641faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 642faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 643d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 644d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 645faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 646faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 647faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 648faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 649948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 650faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 651faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 652d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 653d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 654faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 655faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 656faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 657948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 658948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 659948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 660faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 661faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 662faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 663d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 664faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 665d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 666d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 667d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (type == 0 && mPrimaryHWVsyncEnabled) { 668d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 669faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 670148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 671d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 672d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 673d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 674d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 675d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 676d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 677148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 678148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 679148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 680148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian if (mEventThread == NULL) { 681148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // This is a temporary workaround for b/7145521. A non-null pointer 682148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // does not mean EventThread has finished initializing, so this 683148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian // is not a correct fix. 684148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian ALOGW("WARNING: EventThread not started, ignoring hotplug"); 685148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian return; 686148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 6879e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 6889e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 6899e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian Mutex::Autolock _l(mStateLock); 690692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (connected) { 691692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); 6929e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } else { 693692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mCurrentState.displays.removeItem(mBuiltinDisplays[type]); 694692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall mBuiltinDisplays[type].clear(); 6959e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian } 6969e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian setTransactionFlags(eDisplayTransactionNeeded); 6979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 6989e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden // Defer EventThread notification until SF has updated mDisplays. 6993ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian } 7008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 7018630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 70281cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) { 703faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 70481cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian getHwComposer().eventControl(disp, event, enabled); 7058630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 7068630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 7074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 7081c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 7109eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian case MessageQueue::TRANSACTION: 7119eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian handleMessageTransaction(); 7129eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian break; 7134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::INVALIDATE: 7144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageTransaction(); 7154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageInvalidate(); 7164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian signalRefresh(); 7174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian case MessageQueue::REFRESH: 7194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian handleMessageRefresh(); 7204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian break; 7214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() { 725e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 7264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 72787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 7284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 7294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() { 732cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 73387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handlePageFlip(); 7344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 7353a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 7364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 737cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 738cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian preComposition(); 739cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian rebuildLayerStacks(); 740cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian setUpHWComposer(); 741cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doDebugFlashRegions(); 742cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposition(); 743cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postComposition(); 744cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 745cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 746cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 747cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 748cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 749cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 750cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 751cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 752cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 753cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 754cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 755cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 756cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 757cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 758cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 759cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 760cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian doComposeSurfaces(hw, Region(hw->bounds())); 761cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 762cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 763cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 7643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 7653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 7663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 767cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->compositionComplete(); 768da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 769cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 770cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 771cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 772cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 773cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 774cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 775cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 776cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 777cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 778bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 779bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian HWComposer& hwc(getHwComposer()); 780bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 781bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian status_t err = hwc.prepare(); 782bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 783bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 784cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 785cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 786cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition() 787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 788cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 7891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 7901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 791cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 7921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (layers[i]->onPreComposition()) { 793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 794cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 795cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 796cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 800a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition() 802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 8031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 8041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t i=0 ; i<count ; i++) { 8061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian layers[i]->onPostComposition(); 807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 8084b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 809faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const HWComposer& hwc = getHwComposer(); 810faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 811faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 812faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (presentFence->isValid()) { 813faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryDispSync.addPresentFence(presentFence)) { 814faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 815faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 816948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 817faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 818faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 819faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 820faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (runningWithoutSyncFramework) { 821faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 822faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (hw->isScreenAcquired()) { 823faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 824faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 825faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 826faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 8274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 8284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 8294b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 830a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall if (presentFence->isValid()) { 8314b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentFence(presentFence); 8324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 8334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 8344b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 8354b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 8364b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 8374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 8384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 8394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 84452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (CC_UNLIKELY(mVisibleRegionsDirty)) { 845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 84687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian mVisibleRegionsDirty = false; 84787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateHwcGeometry(); 848ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 8491eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 85092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 851ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region opaqueRegion; 852ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian Region dirtyRegion; 85313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian Vector< sp<Layer> > layersSortedByZ; 8544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 8557e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Transform& tr(hw->getTransform()); 8567e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian const Rect bounds(hw->getBounds()); 857ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (hw->canDraw()) { 8581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian SurfaceFlinger::computeVisibleRegions(layers, 859ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian hw->getLayerStack(), dirtyRegion, opaqueRegion); 8607e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian 8611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 862ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian for (size_t i=0 ; i<count ; i++) { 8631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 8641eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 865ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian if (s.layerStack == hw->getLayerStack()) { 866a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region drawRegion(tr.transform( 867a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->visibleNonTransparentRegion)); 868a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall drawRegion.andSelf(bounds); 869a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall if (!drawRegion.isEmpty()) { 870ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian layersSortedByZ.add(layer); 871ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian } 87287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 87387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 8743b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 8754297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->setVisibleLayersSortedByZ(layersSortedByZ); 8767e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.set(bounds); 8777e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 8787e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian hw->dirtyRegion.orSelf(dirtyRegion); 8793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 8803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 8823b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 883cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 884028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 8857143316af216fa92c31a60d4407b707637382da1Dan Stoza bool mustRecompose = 8867143316af216fa92c31a60d4407b707637382da1Dan Stoza !(mDisplays[dpy]->getDirtyRegion(false).isEmpty()); 8877143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 888028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 889028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 89052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 89152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian if (hwc.initCheck() == NO_ERROR) { 89252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // build the h/w work list 893a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (CC_UNLIKELY(mHwWorkListDirty)) { 894a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis mHwWorkListDirty = false; 895a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 896a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis sp<const DisplayDevice> hw(mDisplays[dpy]); 897a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const int32_t id = hw->getHwcDisplayId(); 898a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (id >= 0) { 89913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 900a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis hw->getVisibleLayersSortedByZ()); 901a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const size_t count = currentLayers.size(); 902a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis if (hwc.createWorkList(id, count) == NO_ERROR) { 903a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 904a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 905a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 90613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 907a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setGeometry(hw, *cur); 9089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { 909a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis cur->setSkip(true); 910a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 911a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 912a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 913a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 914a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 915a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 916a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 917a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis // set the per-frame data 91892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 920e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 921e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >= 0) { 92213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers( 923cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->getVisibleLayersSortedByZ()); 924e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian const size_t count = currentLayers.size(); 925a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis HWComposer::LayerListIterator cur = hwc.begin(id); 926a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis const HWComposer::LayerListIterator end = hwc.end(id); 927a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 928a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis /* 929a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * update the per-frame h/w composer data for each layer 930a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis * and build the transparent region of the FB 931a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis */ 93213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 933a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis layer->setPerFrameData(hw, *cur); 9341e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian } 93552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 93687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 937a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 93852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian status_t err = hwc.prepare(); 93952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 94038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall 94138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 94238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall sp<const DisplayDevice> hw(mDisplays[dpy]); 94338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall hw->prepareFrame(hwc); 94438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 94552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 946cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 94752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 948cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 949cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 95052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 95192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 953cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (hw->canDraw()) { 954cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 955cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 95602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 95702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 95802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 95902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->flip(hw->swapRegion); 962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->swapRegion.clear(); 96387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 96452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian // inform the h/w that we're done compositing 9654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->compositionComplete(); 9664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 96752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 972841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 973b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 974a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 975a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 976c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 97752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian HWComposer& hwc(getHwComposer()); 978ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall if (hwc.initCheck() == NO_ERROR) { 9792a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian if (!hwc.supportsFramebufferTarget()) { 9802a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // EGL spec says: 9812a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // "surface must be bound to the calling thread's current context, 9822a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian // for the current rendering API." 983875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 9842a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian } 985e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian hwc.commit(); 98652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 98752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 9886da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // make the default display current because the VirtualDisplayDevice code cannot 9896da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // deal with dequeueBuffer() being called outside of the composition loop; however 9906da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // the code below can call glFlush() which is allowed (and does in some case) call 9916da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian // dequeueBuffer(). 9926da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); 9936da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian 99492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 9954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 99613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); 997da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->onSwapBuffersCompleted(hwc); 99852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const size_t count = currentLayers.size(); 999e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian int32_t id = hw->getHwcDisplayId(); 1000e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (id >=0 && hwc.initCheck() == NO_ERROR) { 10011e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 10021e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 100352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1004d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, &*cur); 100552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1006cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } else { 100752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian for (size_t i = 0; i < count; i++) { 1008d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian currentLayers[i]->onLayerDisplayed(hw, NULL); 100952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 1010ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 1011e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 1012e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 1013a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 1014a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 10156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 10166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount(); 10176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 10186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis logFrameStats(); 10196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1024841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1025841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 10267cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 10277cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 10287cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 10297cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 10307cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 10317cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 1032ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 1033ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 1034ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 1035ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1036ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 1037ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 1038ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 1039ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 1040ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 1041ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1042e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 104387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 1044ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 1045ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 1046ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 1047ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 1048ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 10493d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 10523d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 10533d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t count = currentLayers.size(); 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 1059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 106313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!trFlags) continue; 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 10743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1077e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 107892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // here we take advantage of Vector's copy-on-write semantics to 107992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // improve performance by skipping the transaction entirely when 108092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // know that the lists are identical 1081e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1082e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 108392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian if (!curr.isIdenticalTo(draw)) { 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 108592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian const size_t cc = curr.size(); 108693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian size_t dc = draw.size(); 108792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 108892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find the displays that were removed 108992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in drawing state but not in current state) 109092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // also handle displays that changed 109192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: displays that are in both lists) 109292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<dc ; i++) { 1093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (j < 0) { 109592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // in drawing state but not in current state 10963ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (!draw[i].isMainDisplay()) { 109727ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // Call makeCurrent() on the primary display so we can 109827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // be sure that nothing associated with this display 109927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden // is current. 110002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice()); 1101875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext); 110202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i))); 110302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 110402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 11059e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 11067adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(draw[i].type, false); 110702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall mDisplays.removeItem(draw.keyAt(i)); 110892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 110992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian ALOGW("trying to remove the main display"); 111092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 111192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } else { 111292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // this display is in both lists. see if something changed. 1113e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[j]); 11143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian const wp<IBinder>& display(curr.keyAt(j)); 1115111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1116e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // changing the surface is like destroying and 111793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // recreating the DisplayDevice, so we just remove it 111893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // from the drawing state, so that it get re-added 111993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // below. 112002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall sp<DisplayDevice> hw(getDisplayDevice(display)); 112102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall if (hw != NULL) 112202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hw->disconnect(getHwComposer()); 112393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDisplays.removeItem(display); 112493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian mDrawingState.displays.removeItemsAt(i); 112593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian dc--; i--; 112693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian // at this point we must loop to the next item 112793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian continue; 112892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 112993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian 1130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> disp(getDisplayDevice(display)); 113193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (disp != NULL) { 113293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian if (state.layerStack != draw[i].layerStack) { 113393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian disp->setLayerStack(state.layerStack); 113493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 113500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if ((state.orientation != draw[i].orientation) 113600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.viewport != draw[i].viewport) 113700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian || (state.frame != draw[i].frame)) 113800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian { 113900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian disp->setProjection(state.orientation, 11404fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 114193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 114292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 114392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 114492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 114592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian 114692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // find displays that were added 114792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // (ie: in current state but not in drawing state) 114892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t i=0 ; i<cc ; i++) { 1149e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1150e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayDeviceState& state(curr[i]); 1151cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 115299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall sp<DisplaySurface> dispSurface; 1153db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<IGraphicBufferProducer> producer; 1154db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc()); 1155db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 115602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall int32_t hwcDisplayId = -1; 115799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.isVirtualDisplay()) { 115802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // Virtual displays without a surface are dormant: 115902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // they have external state (layer stack, projection, 116002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall // etc.) but no internal state (i.e. a DisplayDevice). 116199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (state.surface != NULL) { 1162db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 116302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1164db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface( 1165db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian *mHwc, hwcDisplayId, state.surface, bq, 116699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall state.displayName); 1167db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian 1168db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = vds; 1169db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian if (hwcDisplayId >= 0) { 1170db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian producer = vds; 1171db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian } else { 1172db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian // There won't be any interaction with HWC for this virtual display, 1173db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian // so the GLES driver can pass buffers directly to the sink. 1174db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian producer = state.surface; 1175db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian } 117699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } 117799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall } else { 1178cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian ALOGE_IF(state.surface!=NULL, 1179cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "adding a supported display, but rendering " 1180cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian "surface is provided (%p), ignoring it", 1181cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian state.surface.get()); 118202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall hwcDisplayId = allocateHwcDisplayId(state.type); 1183cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // for supported (by hwc) displays we provide our 1184cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // own rendering surface 1185db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian dispSurface = new FramebufferSurface(*mHwc, state.type, bq); 1186db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian producer = bq; 1187cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 1188cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian 1189cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian const wp<IBinder>& display(curr.keyAt(i)); 119099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall if (dispSurface != NULL) { 1191cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian sp<DisplayDevice> hw = new DisplayDevice(this, 119219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall state.type, hwcDisplayId, 119319e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall mHwc->getFormat(hwcDisplayId), state.isSecure, 119405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall display, dispSurface, producer, 119505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mRenderEngine->getEGLConfig()); 1196cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setLayerStack(state.layerStack); 1197cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian hw->setProjection(state.orientation, 11984fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown state.viewport, state.frame); 11998dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden hw->setDisplayName(state.displayName); 1200cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mDisplays.add(display, hw); 12011c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (state.isVirtualDisplay()) { 12021c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall if (hwcDisplayId >= 0) { 12031c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall mHwc->setVirtualDisplayProperties(hwcDisplayId, 12041c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getWidth(), hw->getHeight(), 12051c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall hw->getFormat()); 12061c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 12071c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } else { 12087adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall mEventThread->onHotplugReceived(state.type, true); 12091c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall } 121093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian } 121192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 121292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 1213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 12143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 1215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { 12178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 12188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 12198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 12208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 12228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 12238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 12258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 12268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 12278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 12298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 12308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 12328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 12338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 12348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 12358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 12368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 12378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 12388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t i=0; i<count; i++) { 12398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 12408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 12418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 124213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 12431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t layerStack = layer->getDrawingState().layerStack; 12448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (i==0 || currentlayerStack != layerStack) { 12458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 12468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 12478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 12488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 12498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 12508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 12518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 12528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (hw->getLayerStack() == currentlayerStack) { 12538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian if (disp == NULL) { 12548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp = hw; 12558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 125691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = NULL; 12578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 12588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 126291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase if (disp == NULL) { 126391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 126491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // redraw after transform hint changes. See bug 8508397. 126591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase 126691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // could be null when this layer is using a layerStack 126791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // that is not visible on any display. Also can occur at 126891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase // screen off/on times. 126991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase disp = getDefaultDisplayDevice(); 12708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 127191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase layer->updateTransformHint(disp); 12728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 12748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 12758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 12763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 12773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 12783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 1279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 12811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian if (currentLayers.size() > layers.size()) { 12823559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // layers have been added 12833559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 12843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 12853559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 12863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 12873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 12883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 12893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 12903559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 12911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 12923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian for (size_t i=0 ; i<count ; i++) { 12931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 12943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (currentLayers.indexOf(layer) < 0) { 12953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 12963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 12973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 12983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 12991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 13001501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region visibleReg = s.transform.transform( 13011501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian Region(Rect(s.active.w, s.active.h))); 13021501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian invalidateLayerStack(s.layerStack, visibleReg); 13030aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 1304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 13084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 13094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 13104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 13114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 13124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (!mLayersPendingRemoval.isEmpty()) { 13134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 13144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 13154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval[i]->onRemoved(); 13164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 13184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 13194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 13204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 13214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 13224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 13234b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 13244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 13252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 13262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 13274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions( 133187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const LayerVector& currentLayers, uint32_t layerStack, 133287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 1333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1334841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 1335841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 1337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t i = currentLayers.size(); 1343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (i--) { 134413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer = currentLayers[i]; 1345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 13471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 1348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 135087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (s.layerStack != layerStack) 135187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian continue; 135287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1353ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1354ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 1355ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 1357ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1358ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1359ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 1360ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 1361ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 1362ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 1363ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 1365ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1366ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 1367ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 1368ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 1369ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 1370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 1371ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1372a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 1373a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 1374a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 1375a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 1376a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 1377a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 1378a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 1379a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 1380a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 1381a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 1382ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1383ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 1384da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 13854125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 13865219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian Rect bounds(s.transform.transform(layer->computeBounds())); 1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 1388ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 1389ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 1390ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 13914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Transform tr(s.transform); 13924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.transformed()) { 13934fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (tr.preserveRects()) { 13944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transform the transparent region 13952ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = tr.transform(s.activeTransparentRegion); 13964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 13974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transformation too complex, can't do the 13984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // transparent region optimization. 1399a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall transparentRegion.clear(); 14004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 14014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 14022ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian transparentRegion = s.activeTransparentRegion; 14034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 1404ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1406ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 14074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const int32_t layerOrientation = s.transform.getOrientation(); 1408ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (s.alpha==255 && !translucent && 1409ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 1410ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 1411ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 1412ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 1413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1416ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 1417ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1418ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1419ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 1420ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 1421ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 1422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 1424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 1426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 1427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 1428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 14304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1433a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 1434ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 1435ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 1436ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 1437ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1438ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 1439ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 1440ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 1441ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1442ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 1443ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 1444a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 1445ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 14464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 14474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 1448ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1449ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 1452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 145487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 1455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1456ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 14588b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 1459a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 1462a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 1463a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 1467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 147087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& dirty) { 147192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 14724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 14734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian if (hw->getLayerStack() == layerStack) { 14744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 147592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 147692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 147787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 147887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 147987baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip() 1480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 14814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian Region dirtyRegion; 148299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 14834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 14841eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const LayerVector& layers(mDrawingState.layersSortedByZ); 14851eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const size_t count = layers.size(); 14864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian for (size_t i=0 ; i<count ; i++) { 14871eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const sp<Layer>& layer(layers[i]); 148887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region dirty(layer->latchBuffer(visibleRegions)); 14891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 149087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian invalidateLayerStack(s.layerStack, dirty); 14914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 14924da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 14933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 1494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1496ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 1497ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 1498ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian mHwWorkListDirty = true; 1499ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 1500ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 150199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 1502cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 150387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15057143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 15067143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 15077143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 15087143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 15097143316af216fa92c31a60d4407b707637382da1Dan Stoza bool isHwcDisplay = hw->getHwcDisplayId() >= 0; 15107143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 15117143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 15127143316af216fa92c31a60d4407b707637382da1Dan Stoza } 15137143316af216fa92c31a60d4407b707637382da1Dan Stoza 151487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region dirtyRegion(inDirtyRegion); 151587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 1516b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian // compute the invalid region 15174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian uint32_t flags = hw->getFlags(); 15200f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::SWAP_RECTANGLE) { 152129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we can redraw only what's dirty, but since SWAP_RECTANGLE only 152229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // takes a rectangle, we must make sure to update that whole 152329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // rectangle in that case 15244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 15260f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian if (flags & DisplayDevice::PARTIAL_UPDATES) { 152729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // We need to redraw the rectangle that will be updated 1528df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian // (pushed to the framebuffer). 152995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // This is needed because PARTIAL_UPDATES only takes one 15300f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian // rectangle instead of a region (see DisplayDevice::flip()) 15314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->swapRegion.bounds()); 1532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 153329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian // we need to redraw everything (the whole screen) 15344297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian dirtyRegion.set(hw->bounds()); 15354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion = dirtyRegion; 1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15399c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { 1540ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1541ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 1542ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian RenderEngine& engine(getRenderEngine()); 15439c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mat4 colorMatrix = mColorMatrix; 15449c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (mDaltonize) { 15459c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette colorMatrix = colorMatrix * mDaltonizer(); 15469c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 15479c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette engine.beginGroup(colorMatrix); 1548ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian doComposeSurfaces(hw, dirtyRegion); 1549ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian engine.endGroup(); 1550ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15529c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian // update the swap region and clear the dirty region 15534297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->swapRegion.orSelf(dirtyRegion); 1554da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 1555da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 1556da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1559cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 15613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 156285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const int32_t id = hw->getHwcDisplayId(); 15638630320433bd15aca239522e54e711ef6372ab07Mathias Agopian HWComposer& hwc(getHwComposer()); 15641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian HWComposer::LayerListIterator cur = hwc.begin(id); 15651e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian const HWComposer::LayerListIterator end = hwc.end(id); 1566a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1567d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall bool hasGlesComposition = hwc.hasGlesComposition(id); 156885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (hasGlesComposition) { 1569875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) { 1570c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 1571c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock hw->getDisplayName().string()); 1572c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock return; 1573c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 1574a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 1575a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 157685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const bool hasHwcComposition = hwc.hasHwcComposition(id); 1577e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian if (hasHwcComposition) { 1578b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 1579b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 1580b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 15813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 1582b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 15833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 0); 1584b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 1585766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we start with the whole screen area 1586766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region bounds(hw->getBounds()); 1587766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1588766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we remove the scissor part 1589766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 1590766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 1591766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Region letterbox(bounds.subtract(hw->getScissor())); 1592766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1593766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 1594766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian Region region(hw->undefinedRegion.merge(letterbox)); 1595766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1596766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // but limit it to the dirty region 1597766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian region.andSelf(dirty); 1598766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 1599b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 160087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 1601b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 160255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian drawWormhole(hw, region); 1603b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 1604a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1605f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1606766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 1607766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 1608f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 1609f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 1610f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian const Rect& bounds(hw->getBounds()); 1611766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian const Rect& scissor(hw->getScissor()); 1612f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 1613f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 1614f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 1615f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 16163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1617f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 16183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian const uint32_t height = hw->getHeight(); 16193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setScissor(scissor.left, height - scissor.bottom, 16203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 1621f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 1622f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 162385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 16244b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 162585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 162685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 162785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 16284b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 162913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); 163085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const size_t count = layers.size(); 163185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Transform& tr = hw->getTransform(); 163285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (cur != end) { 163385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're using h/w composer 163485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 163513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 16364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 163785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 163885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian switch (cur->getCompositionType()) { 163985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_OVERLAY: { 1640ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 164185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if ((cur->getHints() & HWC_HINT_CLEAR_FB) 164285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && i 16434125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden && layer->isOpaque(state) && (state.alpha == 0xFF) 164485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian && hasGlesComposition) { 1645cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // never clear the very first layer since we're 1646cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // guaranteed the FB is already cleared 1647cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->clearWithOpenGL(hw, clip); 1648cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 164985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 165085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 165185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian case HWC_FRAMEBUFFER: { 1652cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian layer->draw(hw, clip); 165385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian break; 1654a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 1655da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian case HWC_FRAMEBUFFER_TARGET: { 1656da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // this should not happen as the iterator shouldn't 1657da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // let us get there. 1658da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i); 1659da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian break; 1660da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian } 1661cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1662a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall } 166385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->setAcquireFence(hw, *cur); 166485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 166585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } else { 166685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian // we're not using h/w composer 166785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 166813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(layers[i]); 166985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian const Region clip(dirty.intersect( 167085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian tr.transform(layer->visibleRegion))); 167185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian if (!clip.isEmpty()) { 167285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian layer->draw(hw, clip); 167385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 16744b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 16754b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 1676f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 1677f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 16783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableScissor(); 1679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const { 168255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian const int32_t height = hw->getHeight(); 16833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 16843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1687ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client, 1688ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 16896710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 169013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& lbc) 16911b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 169296f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 1693ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 16944f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 169596f0819f81293076e652792794a961543e6750d7Mathias Agopian // add this layer to the current state list 1696921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian Mutex::Autolock _l(mStateLock); 1697921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian mCurrentState.layersSortedByZ.add(lbc); 16986710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mGraphicBufferProducerList.add(gbc->asBinder()); 169996f0819f81293076e652792794a961543e6750d7Mathias Agopian} 170096f0819f81293076e652792794a961543e6750d7Mathias Agopian 17013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { 170296f0819f81293076e652792794a961543e6750d7Mathias Agopian Mutex::Autolock _l(mStateLock); 170313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian ssize_t index = mCurrentState.layersSortedByZ.remove(layer); 1704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (index >= 0) { 17056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian mLayersPendingRemoval.push(layer); 1706076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved = true; 17076710604286401d4205c27235a252dd0e5008cc08Mathias Agopian setTransactionFlags(eTransactionNeeded); 1708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 1709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 17103d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian return status_t(index); 1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) { 1714dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 1715dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 1716dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 17173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 1718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 1719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 172499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17298b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 17308b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<ComposerState>& state, 17318b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 17328b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 17338b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 17347c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 1735698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 173628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 1737e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 17382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17392d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 17402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 17412d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 17427c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 17432d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 17442d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 17457c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 17467c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 17477c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 17482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 17492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 17502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17522d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 1754e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian size_t count = displays.size(); 1755e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1756e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const DisplayState& s(displays[i]); 1757e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags |= setDisplayStateLocked(s); 1758b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 1759b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 1760e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian count = state.size(); 1761698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian for (size_t i=0 ; i<count ; i++) { 1762698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian const ComposerState& s(state[i]); 1763d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // Here we need to check that the interface we're given is indeed 1764d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // one of our own. A malicious client could give us a NULL 1765d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // IInterface, or one of its own or even one of our own but a 1766d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // different type. All these situations would cause us to crash. 1767d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // 1768d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // NOTE: it would be better to use RTTI as we could directly check 1769d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian // that we have a Client*. however, RTTI is disabled in Android. 1770d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (s.client != NULL) { 1771d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<IBinder> binder = s.client->asBinder(); 1772d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (binder != NULL) { 1773d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian String16 desc(binder->getInterfaceDescriptor()); 1774d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian if (desc == ISurfaceComposerClient::descriptor) { 1775d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian sp<Client> client( static_cast<Client *>(s.client.get()) ); 1776d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian transactionFlags |= setClientStateLocked(client, s.state); 1777d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1778d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1779d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian } 1780698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 1781386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 178228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 1783386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 178428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis setTransactionFlags(transactionFlags); 1785698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 1786386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 1787386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 1788386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 17892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 17902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 17912d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 17922d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 1793386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 17942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 1795386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1796386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 1797386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 1798386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 17992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 18002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 1801386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 1802386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 1803cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 1804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 18099a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 18109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 18119a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 18129a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 1813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 18149a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 18153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 1818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.surface->asBinder() != s.surface->asBinder()) { 1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 1820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 1824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 1825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 1826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1828e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 182900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 1830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 1831e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 1832e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1833e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1834e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 1835e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 1836e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1837e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1838e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 1839e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 1840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 1841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 1847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked( 1848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const sp<Client>& client, 1849e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const layer_state_t& s) 1850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 1851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 185213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 1853e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer != 0) { 1854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 1855e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::ePositionChanged) { 1856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setPosition(s.x, s.y)) 1857e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerChanged) { 1860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1861e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1862e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayer(s.z)) { 1863e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1864e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1865e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1868e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1869e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1870e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eSizeChanged) { 1871e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setSize(s.w, s.h)) { 1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1873e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1874e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eAlphaChanged) { 1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eMatrixChanged) { 1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setMatrix(s.matrix)) 1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eTransparentRegionChanged) { 1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setTransparentRegionHint(s.transparentRegion)) 1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 18874125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden if ((what & layer_state_t::eVisibilityChanged) || 18884125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden (what & layer_state_t::eOpacityChanged)) { 18894125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden // TODO: should we just use an eFlagsChanged for this? 1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setFlags(s.flags, s.mask)) 1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eCropChanged) { 1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setCrop(s.crop)) 1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTraversalNeeded; 1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & layer_state_t::eLayerStackChanged) { 1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // NOTE: index needs to be calculated before we update the state 1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (layer->setLayerStack(s.layerStack)) { 1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 1909e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 1910e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 1911e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 19124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 19130ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 19140ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 19154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 19164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) 1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 19196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 1920921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 19216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 19224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 19236e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 19248b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 19254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 19264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 19274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 19284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 19293165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 19303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 19314d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createNormalLayer(client, 19324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, format, 19334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 19353165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceDim: 19364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = createDimLayer(client, 19374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, w, h, flags, 19384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 19394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 19404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 19414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 1942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (result == NO_ERROR) { 19466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian addClientLayer(client, *handle, *gbp, layer); 194796f0819f81293076e652792794a961543e6750d7Mathias Agopian setTransactionFlags(eTransactionNeeded); 1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, 19534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 19544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 1956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 195792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 1959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 1960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 1961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 1963a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1964a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGB_565; 1965a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#else 19668f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 1967a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 1969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1971a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#ifdef NO_RGBX_8888 1972a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian if (format == PIXEL_FORMAT_RGBX_8888) 1973a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian format = PIXEL_FORMAT_RGBA_8888; 1974a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian#endif 1975a8f3e4e53cad835d0d57b85a6ce1b7416e95ba73Mathias Agopian 19764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new Layer(this, client, name, w, h, flags); 19774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t err = (*outLayer)->setBuffers(w, h, format, flags); 19784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 19794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 19804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *gbp = (*outLayer)->getBufferQueue(); 1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 19824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 19834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); 19844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 1985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client, 19884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 19894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 19914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *outLayer = new LayerDim(this, client, name, w, h, flags); 19924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 19934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *gbp = (*outLayer)->getBufferQueue(); 19944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 1995118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 1996118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 1997ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 19989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 19996710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by the window manager when it wants to remove a Layer 20006710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 20016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 20026710604286401d4205c27235a252dd0e5008cc08Mathias Agopian if (l != NULL) { 20036710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 20046710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 20056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 20069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 20079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 20089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 20099a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 201013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 2011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20126710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 20136710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 2014ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian status_t err = NO_ERROR; 201513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> l(layer.promote()); 2016ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian if (l != NULL) { 20176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 2018e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 2019ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 2020ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian } 2021ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian return err; 2022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2024b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2025b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 202613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 202701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 202813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 202913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 203013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 203101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 203201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 2033692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 203401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 203513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 20364c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 20374c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 203813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 203913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 2040cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian onScreenAcquired(getDefaultDisplayDevice()); 20416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 20426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const nsecs_t period = 20436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 20446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 204513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 204613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 204713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 204813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 204913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 205013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 205113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 205213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 205313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 205413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 205513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 205613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 205713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 205813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 205913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 206013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 206113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 2062cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { 2063c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this); 2064c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (hw->isScreenAcquired()) { 2065c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // this is expected, e.g. when power manager wakes up during boot 2066c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously acquired"); 2067c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2068c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2069c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 20704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->acquireScreen(); 2071c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 20729e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 2073c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2074c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().acquire(type); 2075c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2076c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2077c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 2078c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 2079faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 2080948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 2081c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2082cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 208320128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian mVisibleRegionsDirty = true; 208420128300e0cb7f459a60cfbcddb48190ce6545edMathias Agopian repaintEverything(); 2085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2087cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopianvoid SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { 2088c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this); 2089c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (!hw->isScreenAcquired()) { 2090c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden ALOGD(" screen was previously released"); 2091c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 2092c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 2093c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2094c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden hw->releaseScreen(); 2095c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden int32_t type = hw->getDisplayType(); 20969e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 2097c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden if (type == DisplayDevice::DISPLAY_PRIMARY) { 2098948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 2099948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 2100cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 2101cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 2102cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 2103c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 2104c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // built-in display, tell the HWC 2105c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden getHwComposer().release(type); 2106b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2107c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mVisibleRegionsDirty = true; 2108c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // from this point on, SF will stop drawing on this display 2109b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2110b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2111c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::unblank(const sp<IBinder>& display) { 2112b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenAcquired : public MessageBase { 2113db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2114db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2115b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2116db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenAcquired(SurfaceFlinger& flinger, 2117db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2118b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2119db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2120db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2121db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to unblank null display %p", mDisplay.get()); 21229e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 2123db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to unblank virtual display"); 2124db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2125db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenAcquired(hw); 2126db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2127b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2128b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2129b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2130db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenAcquired(*this, display); 2131db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2134c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFaddenvoid SurfaceFlinger::blank(const sp<IBinder>& display) { 2135b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian class MessageScreenReleased : public MessageBase { 2136db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 2137db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 2138b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 2139db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian MessageScreenReleased(SurfaceFlinger& flinger, 2140db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { } 2141b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 2142db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 2143db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian if (hw == NULL) { 2144db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGE("Attempt to blank null display %p", mDisplay.get()); 21459e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 2146db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian ALOGW("Attempt to blank virtual display"); 2147db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 2148db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian mFlinger.onScreenReleased(hw); 2149db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 2150b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 2151b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 2152b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 2153db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<MessageBase> msg = new MessageScreenReleased(*this, display); 2154db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 2155b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 2156b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2157b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 2158b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 2159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 216299b49840d309727678b77403d6cc9f920111623fMathias Agopian 2163bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2164bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 2165bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 2166bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 2167bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 216874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 2169bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 2170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 21719795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // Try to get the main lock, but don't insist if we can't 21729795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 21739795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 21749795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian int retry = 3; 21759795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian while (mStateLock.tryLock()<0 && --retry>=0) { 21769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian usleep(1000000); 21779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 21789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian const bool locked(retry >= 0); 21799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 218074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append( 21819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "SurfaceFlinger appears to be unresponsive, " 21829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian "dumping anyways (no locks held)\n"); 21839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 21849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 218582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 218682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 218725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 218825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 218925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 219025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 219125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 219274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 219335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 219425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 219525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 219625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 219725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 219882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 219974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 220035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 220182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 220225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 220325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 220425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 220525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 220674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 220735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 220825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 22101b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 221182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 221274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpAllLocked(args, index, result); 221382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 221448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 221582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 221682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 221748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 221882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 221982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 222082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 222182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 222248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 222325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 222474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 222525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 222625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 222725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 222825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 222913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 223074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 223125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 223225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 223325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 223482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 223574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 223682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 223782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 223882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 223982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 224082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 224182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 224248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 22434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const nsecs_t period = 22444b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 22454b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis result.appendFormat("%lld\n", period); 22464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 22474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 22484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.dump(result); 22494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 22504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 22514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis const size_t count = currentLayers.size(); 22524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis for (size_t i=0 ; i<count ; i++) { 225313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 22544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 225574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian layer->dumpStats(result); 22564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 225782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 225882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 225982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 2260ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 226125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 226274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) 226325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 226425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 226525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 226625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 226725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 226825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 226925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 227025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 227125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian const size_t count = currentLayers.size(); 227225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian for (size_t i=0 ; i<count ; i++) { 227313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 227425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 227525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian layer->clearStats(); 227625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 227725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 22784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 22794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.clear(); 228025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 228125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 22826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 22836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 22846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 22856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const LayerVector& drawingLayers = mDrawingState.layersSortedByZ; 22866547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const size_t count = drawingLayers.size(); 22876547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis for (size_t i=0 ; i<count ; i++) { 22886547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis const sp<Layer>& layer(drawingLayers[i]); 22896547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 22906547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 22916547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 22926547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 22936547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 22946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 22954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 22964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 22974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden static const char* config = 22984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " [sf" 22994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NO_RGBX_8888 23004803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NO_RGBX_8888" 23014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY 23034803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " HAS_CONTEXT_PRIORITY" 23044803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23054803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 23064803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " NEVER_DEFAULT_TO_ASYNC_MODE" 23074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 23094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden " TARGET_DISABLE_TRIPLE_BUFFERING" 23104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif 23114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden "]"; 23124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append(config); 23134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 23144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 231574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 231674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 231782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 23183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 23193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 23203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 23213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 23223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 23233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 23243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 23253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 23263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 232782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 232882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 232982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 233082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 233182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 233282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2333bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 233482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 23364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 23373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 23383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 23394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 23403e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 23414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 23424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 23434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 23444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 23454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 23463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 2347ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 23483e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 2349ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 2350ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 2351ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 23524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 235382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 235482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 235582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 235682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const size_t count = currentLayers.size(); 23573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 235874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Visible layers (count = %d)\n", count); 23593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 236082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian for (size_t i=0 ; i<count ; i++) { 236113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& layer(currentLayers[i]); 23623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian layer->dump(result, colorizer); 236382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 2364bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 236582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 23665f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 23675f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 23685f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 237074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Displays (%d entries)\n", mDisplays.size()); 23713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 23725f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 23735f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 237474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 23755f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 23765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 23775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 237882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 237982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 23801b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 23813e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 238274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 23833e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 23841b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 2385888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 23864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2387ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 23883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 23893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("EGL implementation : %s\n", 23903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION)); 23913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 23923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian result.appendFormat("%s\n", 2393ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS)); 2394ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 2395875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mRenderEngine->dump(result); 23969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 23974297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->undefinedRegion.dump(result, "undefinedRegion"); 239874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" orientation=%d, canDraw=%d\n", 23994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->getOrientation(), hw->canDraw()); 240074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 240182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 240282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 2403c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 240482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 240582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 2406ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 2407ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 2408ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 240982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 241082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 2411c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 2412b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2413b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2414ed985574148a938bc3af24442eead313cc62521cMathias Agopian hwc.getDpiY(HWC_DISPLAY_PRIMARY), 2415ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 241774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 241882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 241982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 242182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 242282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 242482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 242674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 242982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 24313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 243274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 24333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 243474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" h/w composer %s and %s\n", 243582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian hwc.initCheck()==NO_ERROR ? "present" : "not present", 24369c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette (mDebugDisableHWC || mDebugRegion || mDaltonize 24379c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette || mHasColorMatrix) ? "disabled" : "enabled"); 243874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 243982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 244182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 244282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 244382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 244482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 2445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 244713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 244848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 2449db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 245048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 245148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 245248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 245348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 245448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 245548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 245648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 245748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (dpy == NULL) { 245848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 245948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 246048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 246148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 246248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall return getDisplayDevice(dpy)->getVisibleLayersSortedByZ(); 2463cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 2464cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 246563f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 246663f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 246763f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 246863f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 246963f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 247063f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 247163f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 247263f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 247363f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 247463f165fd6b86d04be94d4023e845e98560504a96Keun young Park (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start"); 247563f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 247663f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 247763f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 247863f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 247963f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 248063f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 248163f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 248263f165fd6b86d04be94d4023e845e98560504a96Keun young Park 2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact( 2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 2487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 2488041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 2489698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian case SET_TRANSACTION_STATE: 2490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 24918e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case BLANK: 24928e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross case UNBLANK: 2493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 2495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 2497a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 249899b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 249999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2500e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2501375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2502375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25041b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 25051b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 25071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 25081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 25091b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 25101b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 25111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 251299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 251399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2514e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 25151b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian "can't read framebuffer pid=%d, uid=%d", pid, uid); 25161b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 25171b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 25181b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 2519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25211b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2524b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 252599ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2526375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 2527375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 2528375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 2529e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 2530375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 253501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 253635b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 2539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 2540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 254153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 254253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 254553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 2546cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2547cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 2548cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 2549e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 2550e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 2551e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 2552e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 2553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 25554d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 25564d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 25574d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 25584d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 255953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 256053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 256153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 256253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 256353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 256453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 2565a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 2566a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 2567a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 2568a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 2569a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 2570a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 257201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 2573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 2574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 2575b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 257612839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 2579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mStateLock); 25804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 25814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 2582ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 2583ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2584ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 2585ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 2586ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 2587ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 2588ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1: mDaltonizer.setType(Daltonizer::protanomaly); break; 2589ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break; 2590ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 3: mDaltonizer.setType(Daltonizer::tritanomaly); break; 2591ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2592ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 2593ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::correction); 2594ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 2595ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonizer.setMode(Daltonizer::simulation); 2596ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 2597ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mDaltonize = n > 0; 2598ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian invalidateHwcGeometry(); 2599ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian repaintEverything(); 26009c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 26019c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 26029c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 26039c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 26049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 26059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mHasColorMatrix = n ? 1 : 0; 26069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 26079c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // color matrix is sent as mat3 matrix followed by vec3 26089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // offset, then packed into a mat4 where the last row is 26099c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // the offset and extra values are 0 2610794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 2611794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t j = 0; j < 4; j++) { 2612794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette mColorMatrix[i][j] = data.readFloat(); 2613794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette } 26149c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 26159c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 26169c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette mColorMatrix = mat4(); 26179c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 26189c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette invalidateHwcGeometry(); 26199c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette repaintEverything(); 26209c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 2621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 2625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 262753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() { 262887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 262999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 263053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 263153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 263259119e658a12279e8fff508f8773843de2d90917Mathias Agopian// --------------------------------------------------------------------------- 26332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer 26342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// --------------------------------------------------------------------------- 263559119e658a12279e8fff508f8773843de2d90917Mathias Agopian 26362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824 26372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 26382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls 26392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * to the calling binder thread, where they are executed. This allows 26402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * the calling thread to be reused (on the other side) and not 26412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * depend on having "enough" binder threads to handle the requests. 26422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * 26432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 26442ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 26452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler { 26462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<IGraphicBufferProducer> impl; 26472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<Looper> looper; 26482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t result; 26492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitPending; 26502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian bool exitRequested; 26512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian mutable Barrier barrier; 26522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian volatile int32_t memoryBarrier; 26532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian uint32_t code; 26542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel const* data; 26552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian Parcel* reply; 26562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 26572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian enum { 26582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_API_CALL, 26592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian MSG_EXIT 26602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian }; 26612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 26622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 26632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * this is called by our "fake" BpGraphicBufferProducer. We package the 26642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * data and reply Parcel and forward them to the calling thread. 26652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 26662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual status_t transact(uint32_t code, 26672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian const Parcel& data, Parcel* reply, uint32_t flags) { 26682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->code = code; 26692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->data = &data; 26702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian this->reply = reply; 26712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian android_atomic_acquire_store(0, &memoryBarrier); 26722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (exitPending) { 26732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // if we've exited, we run the message synchronously right here 26742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian handleMessage(Message(MSG_API_CALL)); 26752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else { 26762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.close(); 26772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_API_CALL)); 26782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.wait(); 26792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 26802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return NO_ERROR; 26812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 26822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 26832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian /* 26842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * here we run on the binder calling thread. All we've got to do is 26852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * call the real BpGraphicBufferProducer. 26862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */ 26872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian virtual void handleMessage(const Message& message) { 26882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian android_atomic_release_load(&memoryBarrier); 26892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian if (message.what == MSG_API_CALL) { 26902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian impl->asBinder()->transact(code, data[0], reply); 26912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian barrier.open(); 26922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } else if (message.what == MSG_EXIT) { 26932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitRequested = true; 26942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 26952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 26962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 26972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 26982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl) : 26992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian impl(impl), looper(new Looper(true)), result(NO_ERROR), 27002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending(false), exitRequested(false) { 27012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 27022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t waitForResponse() { 27042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian do { 27052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->pollOnce(-1); 27062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } while (!exitRequested); 27072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian return result; 27082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 27092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian void exit(status_t result) { 2711aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen this->result = result; 27122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian exitPending = true; 27132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian looper->sendMessage(this, Message(MSG_EXIT)); 27142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 27152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 27162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 27192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 27202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, 27213ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) { 27222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 27232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(display == 0)) 27242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 27252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 27262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (CC_UNLIKELY(producer == 0)) 27272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return BAD_VALUE; 27282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 27295ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // if we have secure windows on this display, never allow the screen capture 27305ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // unless the producer interface is local (i.e.: we can take a screenshot for 27315ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian // ourselves). 27325ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (!producer->asBinder()->localBinder()) { 27335ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian Mutex::Autolock _l(mStateLock); 27345ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian sp<const DisplayDevice> hw(getDisplayDevice(display)); 27355ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian if (hw->getSecureLayerVisible()) { 27365ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian ALOGW("FB is protected: PERMISSION_DENIED"); 27375ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian return PERMISSION_DENIED; 27385ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 27395ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian } 27405ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian 27412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian class MessageCaptureScreen : public MessageBase { 27422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian SurfaceFlinger* flinger; 27432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IBinder> display; 27442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<IGraphicBufferProducer> producer; 27452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, reqHeight; 27462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t minLayerZ,maxLayerZ; 27472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t result; 27482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian public: 27492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian MessageCaptureScreen(SurfaceFlinger* flinger, 27502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IBinder>& display, 27512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 27522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, 27533ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 27542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian : flinger(flinger), display(display), producer(producer), 27552a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian reqWidth(reqWidth), reqHeight(reqHeight), 27562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 27572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian result(PERMISSION_DENIED) 27582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian { 27592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 27602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian status_t getResult() const { 27612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return result; 27622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 27632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian virtual bool handler() { 27642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 27652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<const DisplayDevice> hw(flinger->getDisplayDevice(display)); 27660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = flinger->captureScreenImplLocked(hw, 27673ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian producer, reqWidth, reqHeight, minLayerZ, maxLayerZ); 27682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result); 27692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return true; 27702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 27712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian }; 27722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 27739eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // make sure to process transactions before screenshots -- a transaction 27749eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // might already be pending but scheduled for VSYNC; this guarantees we 27759eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // will handle it before the screenshot. When VSYNC finally arrives 27769eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // the scheduled transaction will be a no-op. If no transactions are 27779eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian // scheduled at this time, this will end-up being a no-op as well. 27789eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian mEventQueue.invalidateTransactionNow(); 27799eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian 27802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // this creates a "fake" BBinder which will serve as a "fake" remote 27812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // binder to receive the marshaled calls and forward them to the 27822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // real remote (a BpGraphicBufferProducer) 27832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer); 27842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // the asInterface() call below creates our "fake" BpGraphicBufferProducer 27862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian // which does the marshaling work forwards to our "fake remote" above. 27872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian sp<MessageBase> msg = new MessageCaptureScreen(this, 27882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian display, IGraphicBufferProducer::asInterface( wrapper ), 27893ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian reqWidth, reqHeight, minLayerZ, maxLayerZ); 27902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 27912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian status_t res = postMessageAsync(msg); 27922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian if (res == NO_ERROR) { 27932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian res = wrapper->waitForResponse(); 27942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 27952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian return res; 2796118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 2797118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 2798180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2799180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked( 2800180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<const DisplayDevice>& hw, 2801180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, 2802180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ, 2803180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian bool yswap) 2804180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{ 2805180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 28063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine(getRenderEngine()); 2807180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2808180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 2809180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 2810180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 2811180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const bool filtering = reqWidth != hw_w || reqWidth != hw_h; 2812180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2813180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 28143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 2815180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2816180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 28173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.setViewportAndProjection(reqWidth, reqHeight, hw_w, hw_h, yswap); 28183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 2819180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2820180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 28213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.clearWithColor(0, 0, 0, 1); 2822180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2823180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 2824180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const size_t count = layers.size(); 2825180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 2826180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const sp<Layer>& layer(layers[i]); 28271eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& state(layer->getDrawingState()); 2828180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.layerStack == hw->getLayerStack()) { 2829180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (state.z >= minLayerZ && state.z <= maxLayerZ) { 2830180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (layer->isVisible()) { 2831180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(true); 2832180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian layer->draw(hw); 2833180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if (filtering) layer->setFiltering(false); 2834180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 2835180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 2836180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 2837180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 2838180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2839180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // compositionComplete is needed for older driver 2840180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian hw->compositionComplete(); 2841931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian hw->setViewportAndProjection(); 2842180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 2843180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2844180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 28452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked( 28462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<const DisplayDevice>& hw, 28472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian const sp<IGraphicBufferProducer>& producer, 28482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian uint32_t reqWidth, uint32_t reqHeight, 28493ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t minLayerZ, uint32_t maxLayerZ) 285074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{ 2851fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 2852fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian 2853180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 2854180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_w = hw->getWidth(); 2855180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian const uint32_t hw_h = hw->getHeight(); 2856180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2857180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian if ((reqWidth > hw_w) || (reqHeight > hw_h)) { 2858180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ALOGE("size mismatch (%d, %d) > (%d, %d)", 2859180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth, reqHeight, hw_w, hw_h); 2860180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian return BAD_VALUE; 2861180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian } 2862180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 2863180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqWidth = (!reqWidth) ? hw_w : reqWidth; 2864180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian reqHeight = (!reqHeight) ? hw_h : reqHeight; 2865180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 28660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create a surface (because we're a producer, and we need to 28670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dequeue/queue a buffer) 286883cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall sp<Surface> sur = new Surface(producer, false); 28690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindow* window = sur.get(); 287074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 28710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian status_t result = NO_ERROR; 28720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) { 28733ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 28743ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 28752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 28760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian int err = 0; 28770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight); 28784ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 28790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888); 28800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian err |= native_window_set_usage(window, usage); 28812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 28820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (err == NO_ERROR) { 28830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ANativeWindowBuffer* buffer; 28840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian /* TODO: Once we have the sync framework everywhere this can use 28850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian * server-side waits on the fence that dequeueBuffer returns. 28860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian */ 28870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = native_window_dequeue_buffer_and_wait(window, &buffer); 28880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (result == NO_ERROR) { 28890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // create an EGLImage from the buffer so we can later 28900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // turn it into a texture 28910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, 28920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian EGL_NATIVE_BUFFER_ANDROID, buffer, NULL); 28930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian if (image != EGL_NO_IMAGE_KHR) { 28943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // this binds the given EGLImage as a framebuffer for the 28953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // duration of this scope. 28963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image); 28973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian if (imageBond.getStatus() == NO_ERROR) { 28980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // this will in fact render into our dequeued buffer 28990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // via an FBO, which means we didn't have to create 29000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // an EGLSurface and therefore we're not 29010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // dependent on the context's EGLConfig. 29020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian renderScreenImplLocked(hw, reqWidth, reqHeight, 29030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian minLayerZ, maxLayerZ, true); 2904d555684cb36dfb959694db76962e570184f98838Mathias Agopian 29052d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // Create a sync point and wait on it, so we know the buffer is 29062d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // ready before we pass it along. We can't trivially call glFlush(), 29072d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // so we use a wait flag instead. 29082d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // TODO: pass a sync fd to queueBuffer() and let the consumer wait. 29092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); 29102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (sync != EGL_NO_SYNC_KHR) { 29112d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, 29122d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/); 29132d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden EGLint eglErr = eglGetError(); 29142d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden eglDestroySyncKHR(mEGLDisplay, sync); 29152d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden if (result == EGL_TIMEOUT_EXPIRED_KHR) { 29162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW("captureScreen: fence wait timed out"); 29172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 29182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW_IF(eglErr != EGL_SUCCESS, 29192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden "captureScreen: error waiting on EGL fence: %#x", eglErr); 29202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 29212d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } else { 29222d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError()); 29232d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden // not fatal 29242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden } 29252d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden 2926d555684cb36dfb959694db76962e570184f98838Mathias Agopian if (DEBUG_SCREENSHOTS) { 2927d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 2928d555684cb36dfb959694db76962e570184f98838Mathias Agopian getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 2929d555684cb36dfb959694db76962e570184f98838Mathias Agopian checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, 2930d555684cb36dfb959694db76962e570184f98838Mathias Agopian hw, minLayerZ, maxLayerZ); 2931d555684cb36dfb959694db76962e570184f98838Mathias Agopian delete [] pixels; 2932d555684cb36dfb959694db76962e570184f98838Mathias Agopian } 2933d555684cb36dfb959694db76962e570184f98838Mathias Agopian 29340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 29350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot"); 29360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = INVALID_OPERATION; 29370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } 29380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian // destroy our image 29390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian eglDestroyImageKHR(mEGLDisplay, image); 29400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 29410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 294274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 29430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian window->queueBuffer(window, buffer, -1); 294474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 29450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian } else { 29460aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian result = BAD_VALUE; 294774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 29480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 294974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian } 295074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 295174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian return result; 295274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 295374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 2954d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 2955d555684cb36dfb959694db76962e570184f98838Mathias Agopian const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) { 2956fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 2957d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t y=0 ; y<h ; y++) { 2958d555684cb36dfb959694db76962e570184f98838Mathias Agopian uint32_t const * p = (uint32_t const *)vaddr + y*s; 2959d555684cb36dfb959694db76962e570184f98838Mathias Agopian for (size_t x=0 ; x<w ; x++) { 2960fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 2961fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 2962fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 2963fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("*** we just took a black screenshot ***\n" 2964fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian "requested minz=%d, maxz=%d, layerStack=%d", 2965fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian minLayerZ, maxLayerZ, hw->getLayerStack()); 2966fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const LayerVector& layers( mDrawingState.layersSortedByZ ); 2967fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const size_t count = layers.size(); 2968fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian for (size_t i=0 ; i<count ; ++i) { 2969fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const sp<Layer>& layer(layers[i]); 2970fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 2971fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const bool visible = (state.layerStack == hw->getLayerStack()) 2972fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (state.z >= minLayerZ && state.z <= maxLayerZ) 2973fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian && (layer->isVisible()); 2974fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian ALOGE("%c index=%d, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", 2975fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian visible ? '+' : '-', 2976fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian i, layer->getName().string(), state.layerStack, state.z, 2977fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian layer->isVisible(), state.flags, state.alpha); 2978fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 2979fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 2980fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian} 2981fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 29821b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 29831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 2984921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() { 2985921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2986921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2987921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 298813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian : SortedVector<sp<Layer> >(rhs) { 2989921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 2990921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 2991921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2992921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian const void* rhs) const 2993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2994be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian // sort layers per layer-stack, then by z-order and finally by sequence 299513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); 299613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); 2997be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 29981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t ls = l->getCurrentState().layerStack; 29991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rs = r->getCurrentState().layerStack; 3000be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (ls != rs) 3001be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return ls - rs; 3002be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 30031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t lz = l->getCurrentState().z; 30041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian uint32_t rz = r->getCurrentState().z; 3005be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian if (lz != rz) 3006be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return lz - rz; 3007be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian 3008be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian return l->sequence - r->sequence; 3009921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 3010921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 3011921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// --------------------------------------------------------------------------- 3012921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 30133ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 30143ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian : type(DisplayDevice::DISPLAY_ID_INVALID) { 3015e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3016e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 30173ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 301801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0) { 3019da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian viewport.makeInvalid(); 3020da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian frame.makeInvalid(); 3021b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian} 30227303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3023b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 302496f0819f81293076e652792794a961543e6750d7Mathias Agopian 3025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 30263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 30273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 30283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 30293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 30303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 30313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 30323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 30333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 30343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 3035